micro-models-agent 0.36.0 → 0.36.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +439 -184
- package/package.json +45 -45
package/dist/main.js
CHANGED
|
@@ -2142,7 +2142,7 @@ var init_config = __esm(() => {
|
|
|
2142
2142
|
css: {
|
|
2143
2143
|
command: "npx",
|
|
2144
2144
|
args: ["vscode-css-languageserver", "--stdio"],
|
|
2145
|
-
timeout:
|
|
2145
|
+
timeout: 20000,
|
|
2146
2146
|
autoInstall: true,
|
|
2147
2147
|
workspaceMarkers: ["package.json"]
|
|
2148
2148
|
}
|
|
@@ -2785,6 +2785,7 @@ Use this knowledge to answer the user's question.`,
|
|
|
2785
2785
|
{hints}`,
|
|
2786
2786
|
"exec.file_rewrite_warning": "⚠️ File {file} has been rewritten {count} times. Consider a different approach — the current fix strategy is not working.",
|
|
2787
2787
|
"exec.forbidden_cmd": 'STOP using "{cmd}" via the bash tool — it is not a native Windows cmd.exe command and has failed repeatedly this session. Use the dedicated tool instead: grep → the grep tool, ls/dir → list_dir, find → glob, rm → delete_file, sed → edit_file, touch → write_file, which → `where`, cp/mv → move_file, diff → read_file. Do NOT call bash for this purpose again.',
|
|
2788
|
+
"exec.npm_exec_hint": '"could not determine executable to run" — no "bin" for that package/script. Use "npm run <script>" (script must exist in package.json) or "bunx <pkg>" for a package that declares a bin.',
|
|
2788
2789
|
"hall.max_retries_exhausted": "Model returned empty or insufficient responses after multiple retries",
|
|
2789
2790
|
"hall.short_response": "Response too short or empty",
|
|
2790
2791
|
"hall.repetitive": "Response too repetitive ({pct}% overlap)",
|
|
@@ -3383,6 +3384,7 @@ var init_ru = __esm(() => {
|
|
|
3383
3384
|
{hints}`,
|
|
3384
3385
|
"exec.file_rewrite_warning": "⚠️ Файл {file} был перезаписан {count} раз. Попробуйте другой подход — текущая стратегия исправлений не работает.",
|
|
3385
3386
|
"exec.forbidden_cmd": 'ПРЕКРАТИ использовать "{cmd}" через bash — это не команда Windows cmd.exe, и она уже неоднократно падала в этой сессии. Используй предназначенный тул: grep → тул grep, ls/dir → list_dir, find → glob, rm → delete_file, sed → edit_file, touch → write_file, which → `where`, cp/mv → move_file, diff → read_file. Больше не вызывай bash для этого.',
|
|
3387
|
+
"exec.npm_exec_hint": '"could not determine executable to run" — у пакета/скрипта нет "bin". Используй "npm run <script>" (скрипт должен быть в package.json) или "bunx <pkg>" для пакета с объявленным bin.',
|
|
3386
3388
|
"hall.max_retries_exhausted": "Модель вернула пустой или недостаточный ответ после нескольких попыток",
|
|
3387
3389
|
"hall.short_response": "Слишком короткий или пустой ответ",
|
|
3388
3390
|
"hall.repetitive": "Слишком повторяющийся ответ ({pct}% совпадение)",
|
|
@@ -7555,7 +7557,15 @@ function emptyCliRunHint(command, output, code) {
|
|
|
7555
7557
|
return null;
|
|
7556
7558
|
return "the command exited 0 but printed NOTHING to stdout. If this should run a CLI program, the file probably has no entry point: read it with read_file and check the code actually calls its main function with command-line arguments (e.g. main(process.argv[2])) and prints results with console.log.";
|
|
7557
7559
|
}
|
|
7558
|
-
|
|
7560
|
+
function npmExecHint(output) {
|
|
7561
|
+
if (NPM_EXEC_RE.test(output)) {
|
|
7562
|
+
return `${output}
|
|
7563
|
+
|
|
7564
|
+
Hint: ${t("exec.npm_exec_hint")}`;
|
|
7565
|
+
}
|
|
7566
|
+
return output;
|
|
7567
|
+
}
|
|
7568
|
+
var BASH_GRACE_MS = 5000, SPAWN_SETTLE_MS = 100, bashGraceMs, FAILING_FIRST_WORDS, HARD_BLOCK_THRESHOLD = 3, UNIX_TO_WIN_HINTS, UNIX_TO_WIN_TRANSLATE, NEVER_TOOL_CALLS, CLI_FILE_RUN_RE, NPM_EXEC_RE, bashTool;
|
|
7559
7569
|
var init_bash = __esm(() => {
|
|
7560
7570
|
init_command_validator();
|
|
7561
7571
|
init_audit_log();
|
|
@@ -7620,6 +7630,7 @@ var init_bash = __esm(() => {
|
|
|
7620
7630
|
"awk"
|
|
7621
7631
|
]);
|
|
7622
7632
|
CLI_FILE_RUN_RE = /\b(bun|node|deno|python|python3|tsx|ts-node|php|ruby|go\s+run)\S*\s+(run\s+)?["']?[\w./\\-]+\.(ts|js|tsx|jsx|mjs|cjs|py)\b/;
|
|
7633
|
+
NPM_EXEC_RE = /could not determine executable to run/i;
|
|
7623
7634
|
bashTool = {
|
|
7624
7635
|
name: "bash",
|
|
7625
7636
|
description: `Execute a shell command and return its output. Use for running tests, build, git, and shell operations. Commands that are still running after a few seconds are automatically moved to the background and return a process id — manage them with process_list, process_log, process_kill. Set background=true to return a process id immediately for commands you know are long-running (dev servers, watchers).
|
|
@@ -7716,6 +7727,7 @@ ${output2}`;
|
|
|
7716
7727
|
if (!output2 && code !== 0) {
|
|
7717
7728
|
output2 = `(exit code ${code})`;
|
|
7718
7729
|
}
|
|
7730
|
+
output2 = npmExecHint(output2);
|
|
7719
7731
|
if (platform2() === "win32") {
|
|
7720
7732
|
const originalFirstWord = originalCommand.trim().split(/\s+/)[0]?.split(/[\\/]/).pop();
|
|
7721
7733
|
if (originalFirstWord && originalFirstWord in UNIX_TO_WIN_HINTS) {
|
|
@@ -7897,6 +7909,12 @@ var init_process_kill = __esm(() => {
|
|
|
7897
7909
|
});
|
|
7898
7910
|
|
|
7899
7911
|
// src/core/prompt-builder.ts
|
|
7912
|
+
function blockLabel(content) {
|
|
7913
|
+
const firstLine = content.split(`
|
|
7914
|
+
`)[0].trim();
|
|
7915
|
+
return firstLine.length > 70 ? firstLine.slice(0, 67) + "..." : firstLine;
|
|
7916
|
+
}
|
|
7917
|
+
|
|
7900
7918
|
class PromptBuilder {
|
|
7901
7919
|
blocks = [];
|
|
7902
7920
|
budget;
|
|
@@ -7925,24 +7943,41 @@ class PromptBuilder {
|
|
|
7925
7943
|
let usedTokens = 0;
|
|
7926
7944
|
const included = [];
|
|
7927
7945
|
const excluded = [];
|
|
7946
|
+
const blocks = [];
|
|
7928
7947
|
for (const block of essential) {
|
|
7929
7948
|
included.push(block.content);
|
|
7930
7949
|
usedTokens += block.estimatedTokens;
|
|
7950
|
+
blocks.push({
|
|
7951
|
+
label: blockLabel(block.content),
|
|
7952
|
+
priority: block.priority,
|
|
7953
|
+
essential: true,
|
|
7954
|
+
tokens: block.estimatedTokens,
|
|
7955
|
+
included: true
|
|
7956
|
+
});
|
|
7931
7957
|
}
|
|
7932
7958
|
for (const block of nonEssential) {
|
|
7933
7959
|
const tokens = block.estimatedTokens;
|
|
7934
|
-
|
|
7960
|
+
const fits = usedTokens + tokens <= this.budget;
|
|
7961
|
+
if (fits) {
|
|
7935
7962
|
included.push(block.content);
|
|
7936
7963
|
usedTokens += tokens;
|
|
7937
7964
|
} else {
|
|
7938
7965
|
excluded.push(block.content);
|
|
7939
7966
|
}
|
|
7967
|
+
blocks.push({
|
|
7968
|
+
label: blockLabel(block.content),
|
|
7969
|
+
priority: block.priority,
|
|
7970
|
+
essential: false,
|
|
7971
|
+
tokens,
|
|
7972
|
+
included: fits
|
|
7973
|
+
});
|
|
7940
7974
|
}
|
|
7941
7975
|
return {
|
|
7942
7976
|
prompt: included.join(`
|
|
7943
7977
|
|
|
7944
7978
|
`),
|
|
7945
|
-
excluded
|
|
7979
|
+
excluded,
|
|
7980
|
+
blocks
|
|
7946
7981
|
};
|
|
7947
7982
|
}
|
|
7948
7983
|
}
|
|
@@ -8066,14 +8101,54 @@ class SessionLogger {
|
|
|
8066
8101
|
iteration
|
|
8067
8102
|
});
|
|
8068
8103
|
}
|
|
8069
|
-
logCompaction(
|
|
8104
|
+
logCompaction(info) {
|
|
8070
8105
|
this.session?.appendLog({
|
|
8071
8106
|
ts: new Date().toISOString(),
|
|
8072
8107
|
type: "compaction",
|
|
8073
|
-
content,
|
|
8108
|
+
content: `${info.reason}, iteration ${info.iteration}`,
|
|
8109
|
+
iteration: info.iteration,
|
|
8110
|
+
reason: info.reason,
|
|
8111
|
+
tokensBefore: info.tokensBefore,
|
|
8112
|
+
tokensAfter: info.tokensAfter,
|
|
8113
|
+
qualityBefore: info.qualityBefore,
|
|
8114
|
+
qualityAfter: info.qualityAfter,
|
|
8115
|
+
messagesBefore: info.messagesBefore,
|
|
8116
|
+
messagesAfter: info.messagesAfter,
|
|
8117
|
+
removedTurns: info.removedTurns,
|
|
8118
|
+
keptTurns: info.keptTurns,
|
|
8119
|
+
summary: info.summary
|
|
8120
|
+
});
|
|
8121
|
+
}
|
|
8122
|
+
logContext(info) {
|
|
8123
|
+
this.session?.appendLog({
|
|
8124
|
+
ts: new Date().toISOString(),
|
|
8125
|
+
type: "context",
|
|
8126
|
+
content: info.kind === "start" ? "context snapshot at session start" : `context at iteration ${info.iteration}`,
|
|
8127
|
+
iteration: info.iteration,
|
|
8128
|
+
window: info.window,
|
|
8129
|
+
systemBudget: info.systemBudget,
|
|
8130
|
+
reserveBudget: info.reserveBudget,
|
|
8131
|
+
historyBudget: info.historyBudget,
|
|
8132
|
+
systemTokens: info.systemTokens,
|
|
8133
|
+
toolTokens: info.toolTokens,
|
|
8134
|
+
contextTokens: info.tokens,
|
|
8135
|
+
quality: info.quality,
|
|
8136
|
+
messageCount: info.messageCount,
|
|
8137
|
+
compactionCount: info.compactionCount,
|
|
8138
|
+
iterationsSinceCompaction: info.iterationsSinceCompaction,
|
|
8139
|
+
blocks: info.blocks
|
|
8140
|
+
});
|
|
8141
|
+
}
|
|
8142
|
+
logLlmUsage(iteration, usage) {
|
|
8143
|
+
this.session?.appendLog({
|
|
8144
|
+
ts: new Date().toISOString(),
|
|
8145
|
+
type: "llm_usage",
|
|
8074
8146
|
iteration,
|
|
8075
|
-
|
|
8076
|
-
|
|
8147
|
+
promptTokens: usage.promptTokens,
|
|
8148
|
+
completionTokens: usage.completionTokens,
|
|
8149
|
+
totalTokens: usage.totalTokens,
|
|
8150
|
+
source: usage.source,
|
|
8151
|
+
durationMs: usage.durationMs
|
|
8077
8152
|
});
|
|
8078
8153
|
}
|
|
8079
8154
|
logError(message) {
|
|
@@ -10372,7 +10447,36 @@ class Agent {
|
|
|
10372
10447
|
if (pluginBlocks.length > 0) {
|
|
10373
10448
|
builder.addBlocks(pluginBlocks);
|
|
10374
10449
|
}
|
|
10375
|
-
|
|
10450
|
+
const result = builder.build();
|
|
10451
|
+
return {
|
|
10452
|
+
prompt: result.prompt,
|
|
10453
|
+
excluded: result.excluded,
|
|
10454
|
+
blocks: result.blocks
|
|
10455
|
+
};
|
|
10456
|
+
}
|
|
10457
|
+
logContextStat(kind, iteration, slog, blocks) {
|
|
10458
|
+
const cm = this.deps.contextManager;
|
|
10459
|
+
if (typeof cm.getSnapshot !== "function")
|
|
10460
|
+
return;
|
|
10461
|
+
const snap = cm.getSnapshot();
|
|
10462
|
+
const history = cm.getActiveHistory();
|
|
10463
|
+
const systemMsg = history.find((m) => m.role === "system");
|
|
10464
|
+
slog.logContext({
|
|
10465
|
+
kind,
|
|
10466
|
+
iteration,
|
|
10467
|
+
window: snap.window,
|
|
10468
|
+
systemBudget: snap.budget.systemPrompt,
|
|
10469
|
+
reserveBudget: snap.budget.responseReserve,
|
|
10470
|
+
historyBudget: snap.budget.history,
|
|
10471
|
+
systemTokens: kind === "start" && systemMsg && typeof systemMsg.content === "string" ? this.deps.llmProvider.countTokens(systemMsg.content) : undefined,
|
|
10472
|
+
toolTokens: snap.toolTokens,
|
|
10473
|
+
tokens: snap.tokens,
|
|
10474
|
+
quality: snap.quality,
|
|
10475
|
+
messageCount: snap.messageCount,
|
|
10476
|
+
compactionCount: snap.compactionCount,
|
|
10477
|
+
iterationsSinceCompaction: snap.iterationsSinceCompaction,
|
|
10478
|
+
blocks
|
|
10479
|
+
});
|
|
10376
10480
|
}
|
|
10377
10481
|
getSystemPromptInfo() {
|
|
10378
10482
|
const { prompt, excluded } = this.buildSystemPrompt();
|
|
@@ -10532,27 +10636,47 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10532
10636
|
}
|
|
10533
10637
|
});
|
|
10534
10638
|
if (contextManager.needsCompaction()) {
|
|
10535
|
-
contextManager.compact();
|
|
10536
|
-
|
|
10537
|
-
|
|
10639
|
+
const result = contextManager.compact();
|
|
10640
|
+
if (result) {
|
|
10641
|
+
logger.debug("Context compacted");
|
|
10642
|
+
slog.logCompaction({ reason: "interval", iteration, ...result });
|
|
10643
|
+
}
|
|
10538
10644
|
}
|
|
10539
10645
|
const currentTokens = contextManager.getEstimatedTokens();
|
|
10540
10646
|
const budget2 = contextManager.getBudget();
|
|
10541
10647
|
const quality = contextManager.getQuality();
|
|
10542
10648
|
if (quality < QUALITY_TRIGGER_THRESHOLD && contextManager.getCompactionCount() > 0 && iteration - lastForcedCompactionIteration >= FORCED_COMPACTION_COOLDOWN) {
|
|
10543
10649
|
lastForcedCompactionIteration = iteration;
|
|
10544
|
-
contextManager.compact();
|
|
10650
|
+
const result = contextManager.compact();
|
|
10545
10651
|
logger.warn(`Low context quality (${quality}%) — forced compaction`);
|
|
10546
|
-
|
|
10652
|
+
if (result) {
|
|
10653
|
+
slog.logCompaction({
|
|
10654
|
+
reason: `quality-triggered (${quality}% < ${QUALITY_TRIGGER_THRESHOLD}%)`,
|
|
10655
|
+
iteration,
|
|
10656
|
+
...result
|
|
10657
|
+
});
|
|
10658
|
+
}
|
|
10547
10659
|
}
|
|
10548
10660
|
if (currentTokens > budget2.history) {
|
|
10549
|
-
contextManager.compact();
|
|
10661
|
+
const result = contextManager.compact();
|
|
10550
10662
|
logger.warn(`Context overflow (${currentTokens} > ${budget2.history}), forced compaction`);
|
|
10551
|
-
|
|
10663
|
+
if (result) {
|
|
10664
|
+
slog.logCompaction({
|
|
10665
|
+
reason: `overflow (${currentTokens} > ${budget2.history})`,
|
|
10666
|
+
iteration,
|
|
10667
|
+
...result
|
|
10668
|
+
});
|
|
10669
|
+
}
|
|
10552
10670
|
}
|
|
10553
10671
|
this.refreshSystemPrompt();
|
|
10554
10672
|
const history = contextManager.getActiveHistory();
|
|
10555
10673
|
slog.logToolDefs(allToolsForBudget.length, allToolsForBudget.map((t2) => t2.name), iteration);
|
|
10674
|
+
if (iteration === 1) {
|
|
10675
|
+
const { blocks } = this.buildSystemPrompt();
|
|
10676
|
+
this.logContextStat("start", iteration, slog, blocks);
|
|
10677
|
+
} else {
|
|
10678
|
+
this.logContextStat("iteration", iteration, slog);
|
|
10679
|
+
}
|
|
10556
10680
|
let textContent = "";
|
|
10557
10681
|
let reasoningContent = "";
|
|
10558
10682
|
const toolCalls = [];
|
|
@@ -10561,6 +10685,8 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10561
10685
|
const textChunks = [];
|
|
10562
10686
|
this.emitPhase(iteration, "thinking", onPhase);
|
|
10563
10687
|
const llmStart = Date.now();
|
|
10688
|
+
const promptBefore = apiPromptTokens;
|
|
10689
|
+
const completionBefore = apiCompletionTokens;
|
|
10564
10690
|
logger.logLLMRequest(config.model, history.length, input, "agent");
|
|
10565
10691
|
try {
|
|
10566
10692
|
for await (const chunk of llmProvider.chat(history, allToolsForBudget, this.abortController?.signal)) {
|
|
@@ -10624,6 +10750,20 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10624
10750
|
}
|
|
10625
10751
|
apiCompletionChars += (textContent || reasoningContent).length;
|
|
10626
10752
|
logger.logLLMResponse(config.model, (textContent || reasoningContent).length, Date.now() - llmStart, undefined, "agent");
|
|
10753
|
+
{
|
|
10754
|
+
const usagePrompt = apiPromptTokens - promptBefore;
|
|
10755
|
+
const usageCompletion = apiCompletionTokens - completionBefore;
|
|
10756
|
+
const source = usagePrompt > 0 || usageCompletion > 0 ? "api" : "estimate";
|
|
10757
|
+
const prompt = source === "api" ? usagePrompt : contextManager.getEstimatedTokens();
|
|
10758
|
+
const completion = source === "api" ? usageCompletion : Math.ceil((textContent || reasoningContent).length / 4);
|
|
10759
|
+
slog.logLlmUsage(iteration, {
|
|
10760
|
+
promptTokens: prompt,
|
|
10761
|
+
completionTokens: completion,
|
|
10762
|
+
totalTokens: prompt + completion,
|
|
10763
|
+
source,
|
|
10764
|
+
durationMs: Date.now() - llmStart
|
|
10765
|
+
});
|
|
10766
|
+
}
|
|
10627
10767
|
if (this.shutdownRequested) {
|
|
10628
10768
|
break;
|
|
10629
10769
|
}
|
|
@@ -10741,8 +10881,15 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10741
10881
|
slog.logToolResult(call, result, duration, iteration);
|
|
10742
10882
|
}
|
|
10743
10883
|
if (contextManager.needsCompaction()) {
|
|
10744
|
-
contextManager.compact();
|
|
10745
|
-
|
|
10884
|
+
const result2 = contextManager.compact();
|
|
10885
|
+
if (result2) {
|
|
10886
|
+
logger.debug("Context compacted after tool result");
|
|
10887
|
+
slog.logCompaction({
|
|
10888
|
+
reason: "after_tool",
|
|
10889
|
+
iteration,
|
|
10890
|
+
...result2
|
|
10891
|
+
});
|
|
10892
|
+
}
|
|
10746
10893
|
}
|
|
10747
10894
|
if (!result.success) {
|
|
10748
10895
|
const key = call.name;
|
|
@@ -11350,9 +11497,12 @@ class ContextManager {
|
|
|
11350
11497
|
return totalTokens > this.budget.history * this.compactionThreshold;
|
|
11351
11498
|
}
|
|
11352
11499
|
compact() {
|
|
11500
|
+
const tokensBefore = this.getEstimatedTokens();
|
|
11501
|
+
const qualityBefore = this.getQuality();
|
|
11502
|
+
const messagesBefore = this.messages.length;
|
|
11353
11503
|
this.iterationsSinceCompaction = 0;
|
|
11354
11504
|
if (this.messages.length <= KEEP_LAST_N * 2)
|
|
11355
|
-
return;
|
|
11505
|
+
return null;
|
|
11356
11506
|
this.compactionCount++;
|
|
11357
11507
|
const cutoff = this.messages.length - KEEP_LAST_N * 2;
|
|
11358
11508
|
const oldTurns = this.messages.slice(0, cutoff);
|
|
@@ -11406,6 +11556,29 @@ ${lines.join(`
|
|
|
11406
11556
|
if (this.onCompact) {
|
|
11407
11557
|
this.onCompact(summary);
|
|
11408
11558
|
}
|
|
11559
|
+
return {
|
|
11560
|
+
removedTurns: oldTurns.length,
|
|
11561
|
+
keptTurns: freshRecent.length,
|
|
11562
|
+
tokensBefore,
|
|
11563
|
+
tokensAfter: this.getEstimatedTokens(),
|
|
11564
|
+
qualityBefore,
|
|
11565
|
+
qualityAfter: this.getQuality(),
|
|
11566
|
+
messagesBefore,
|
|
11567
|
+
messagesAfter: this.messages.length,
|
|
11568
|
+
summary: this.compactedBlock ?? ""
|
|
11569
|
+
};
|
|
11570
|
+
}
|
|
11571
|
+
getSnapshot() {
|
|
11572
|
+
return {
|
|
11573
|
+
window: this.contextWindow,
|
|
11574
|
+
budget: { ...this.budget },
|
|
11575
|
+
tokens: this.getEstimatedTokens(),
|
|
11576
|
+
toolTokens: this.toolTokens,
|
|
11577
|
+
messageCount: this.messages.length,
|
|
11578
|
+
quality: this.getQuality(),
|
|
11579
|
+
compactionCount: this.compactionCount,
|
|
11580
|
+
iterationsSinceCompaction: this.iterationsSinceCompaction
|
|
11581
|
+
};
|
|
11409
11582
|
}
|
|
11410
11583
|
updateSystemPrompt(content) {
|
|
11411
11584
|
const idx = this.messages.findIndex((m) => m.role === "system");
|
|
@@ -14216,6 +14389,7 @@ class BridgeDriver {
|
|
|
14216
14389
|
proc = null;
|
|
14217
14390
|
rl = null;
|
|
14218
14391
|
pending = new Map;
|
|
14392
|
+
lastStderr = [];
|
|
14219
14393
|
nextId = 1;
|
|
14220
14394
|
lastUrl = "";
|
|
14221
14395
|
console = new ConsoleBuffer(500);
|
|
@@ -14224,9 +14398,13 @@ class BridgeDriver {
|
|
|
14224
14398
|
constructor(opts = {}) {
|
|
14225
14399
|
this.maxConsoleLineChars = opts.maxConsoleLineChars ?? 400;
|
|
14226
14400
|
}
|
|
14227
|
-
async send(cmd, params = {}) {
|
|
14228
|
-
if (!this.proc || !this.rl)
|
|
14229
|
-
|
|
14401
|
+
async send(cmd, params = {}, retried = false) {
|
|
14402
|
+
if (!this.proc || !this.rl) {
|
|
14403
|
+
if (retried || cmd === "close")
|
|
14404
|
+
throw new Error("Bridge is not running");
|
|
14405
|
+
this.spawnBridge();
|
|
14406
|
+
return this.send(cmd, params, true);
|
|
14407
|
+
}
|
|
14230
14408
|
const id = this.nextId++;
|
|
14231
14409
|
const response = await new Promise((resolve15, reject) => {
|
|
14232
14410
|
const timer = setTimeout(() => {
|
|
@@ -14272,7 +14450,10 @@ class BridgeDriver {
|
|
|
14272
14450
|
const script = bridgeScriptPath();
|
|
14273
14451
|
const proc = spawn4("node", [script], { stdio: ["pipe", "pipe", "pipe"], windowsHide: true });
|
|
14274
14452
|
this.proc = proc;
|
|
14275
|
-
|
|
14453
|
+
this.lastStderr = [];
|
|
14454
|
+
proc.stderr.on("data", (chunk) => {
|
|
14455
|
+
this.lastStderr = [...this.lastStderr.slice(-4), chunk.toString()];
|
|
14456
|
+
});
|
|
14276
14457
|
const rl = createInterface({ input: proc.stdout });
|
|
14277
14458
|
this.rl = rl;
|
|
14278
14459
|
rl.on("line", (line) => {
|
|
@@ -14288,15 +14469,28 @@ class BridgeDriver {
|
|
|
14288
14469
|
resolver(resp);
|
|
14289
14470
|
}
|
|
14290
14471
|
});
|
|
14291
|
-
proc.on("
|
|
14292
|
-
|
|
14293
|
-
|
|
14294
|
-
}
|
|
14295
|
-
this.
|
|
14472
|
+
proc.on("error", (err) => {
|
|
14473
|
+
if (this.proc !== proc)
|
|
14474
|
+
return;
|
|
14475
|
+
this.failPending(`Bridge process failed to start: ${err.message}`);
|
|
14476
|
+
this.proc = null;
|
|
14477
|
+
this.rl = null;
|
|
14478
|
+
});
|
|
14479
|
+
proc.on("exit", (code) => {
|
|
14480
|
+
if (this.proc !== proc)
|
|
14481
|
+
return;
|
|
14482
|
+
const stderrTail = this.lastStderr.join("").trim();
|
|
14483
|
+
this.failPending(stderrTail ? `Bridge process exited (code ${code}): ${stderrTail.slice(0, 300)}` : `Bridge process exited (code ${code})`);
|
|
14296
14484
|
this.proc = null;
|
|
14297
14485
|
this.rl = null;
|
|
14298
14486
|
});
|
|
14299
14487
|
}
|
|
14488
|
+
failPending(error) {
|
|
14489
|
+
for (const [, resolver] of this.pending) {
|
|
14490
|
+
resolver({ id: -1, ok: false, error });
|
|
14491
|
+
}
|
|
14492
|
+
this.pending.clear();
|
|
14493
|
+
}
|
|
14300
14494
|
async goto(url, timeoutMs) {
|
|
14301
14495
|
await this.send("goto", { url, timeoutMs });
|
|
14302
14496
|
}
|
|
@@ -15940,8 +16134,8 @@ class PlanTracker {
|
|
|
15940
16134
|
var init_tracker = () => {};
|
|
15941
16135
|
|
|
15942
16136
|
// src/modules/execution/audit-runners.ts
|
|
15943
|
-
import { readdirSync as readdirSync8 } from "fs";
|
|
15944
|
-
import { join as join23 } from "path";
|
|
16137
|
+
import { existsSync as existsSync28, readdirSync as readdirSync8 } from "fs";
|
|
16138
|
+
import { dirname as dirname10, join as join23, resolve as resolve17 } from "path";
|
|
15945
16139
|
function findTestFile(dir, depth = 0) {
|
|
15946
16140
|
if (depth > 5)
|
|
15947
16141
|
return null;
|
|
@@ -16000,7 +16194,7 @@ async function runTests(baseDir) {
|
|
|
16000
16194
|
return {
|
|
16001
16195
|
checked: true,
|
|
16002
16196
|
passed: entry.exitCode === 0,
|
|
16003
|
-
failed: entry.exitCode === 0 ? 0 :
|
|
16197
|
+
failed: entry.exitCode === 0 ? 0 : 1,
|
|
16004
16198
|
passedCount: 0,
|
|
16005
16199
|
detail: output.slice(0, 200).trim(),
|
|
16006
16200
|
command: "bun test"
|
|
@@ -16021,6 +16215,25 @@ function parseTypecheckErrors(output) {
|
|
|
16021
16215
|
`).find((l) => /error TS\d+/.test(l));
|
|
16022
16216
|
return line ? line.trim().slice(0, 300) : null;
|
|
16023
16217
|
}
|
|
16218
|
+
function findTypecheckRoot(baseDir, existingFiles = []) {
|
|
16219
|
+
const candidates = [baseDir, ...existingFiles];
|
|
16220
|
+
let best = null;
|
|
16221
|
+
for (const start of candidates) {
|
|
16222
|
+
let dir = resolve17(start);
|
|
16223
|
+
for (let depth = 0;depth <= 10; depth++) {
|
|
16224
|
+
if (existsSync28(join23(dir, "tsconfig.json"))) {
|
|
16225
|
+
if (!best || depth < best.depth)
|
|
16226
|
+
best = { depth, root: dir };
|
|
16227
|
+
break;
|
|
16228
|
+
}
|
|
16229
|
+
const parent = dirname10(dir);
|
|
16230
|
+
if (parent === dir)
|
|
16231
|
+
break;
|
|
16232
|
+
dir = parent;
|
|
16233
|
+
}
|
|
16234
|
+
}
|
|
16235
|
+
return best?.root ?? null;
|
|
16236
|
+
}
|
|
16024
16237
|
async function runTypecheck(baseDir) {
|
|
16025
16238
|
const entry = processRegistry.start("npx --no-install tsc --noEmit --skipLibCheck", baseDir);
|
|
16026
16239
|
const exited = await processRegistry.waitForExit(entry.id, 90000);
|
|
@@ -16051,11 +16264,11 @@ var init_audit_runners = __esm(() => {
|
|
|
16051
16264
|
});
|
|
16052
16265
|
|
|
16053
16266
|
// src/modules/execution/auditor.ts
|
|
16054
|
-
import { existsSync as
|
|
16055
|
-
import { resolve as
|
|
16267
|
+
import { existsSync as existsSync29, readdirSync as readdirSync9 } from "fs";
|
|
16268
|
+
import { resolve as resolve18, join as join24, basename as basename2 } from "path";
|
|
16056
16269
|
function findExistingFile(baseDir, filePath) {
|
|
16057
|
-
const direct =
|
|
16058
|
-
if (
|
|
16270
|
+
const direct = resolve18(baseDir, filePath);
|
|
16271
|
+
if (existsSync29(direct))
|
|
16059
16272
|
return direct;
|
|
16060
16273
|
const name = basename2(filePath).toLowerCase();
|
|
16061
16274
|
const suffix = filePath.replace(/\\/g, "/").toLowerCase();
|
|
@@ -16103,8 +16316,9 @@ class Auditor {
|
|
|
16103
16316
|
const existingFiles = [];
|
|
16104
16317
|
const leftoverFiles = [];
|
|
16105
16318
|
for (const filePath of createFiles) {
|
|
16106
|
-
|
|
16107
|
-
|
|
16319
|
+
const resolved = findExistingFile(this.baseDir, filePath);
|
|
16320
|
+
if (resolved) {
|
|
16321
|
+
existingFiles.push(resolved);
|
|
16108
16322
|
} else {
|
|
16109
16323
|
missingFiles.push(filePath);
|
|
16110
16324
|
}
|
|
@@ -16123,11 +16337,14 @@ class Auditor {
|
|
|
16123
16337
|
}
|
|
16124
16338
|
}
|
|
16125
16339
|
let typecheckError = null;
|
|
16126
|
-
if (missingFiles.length === 0 && leftoverFiles.length === 0
|
|
16127
|
-
|
|
16128
|
-
|
|
16129
|
-
|
|
16130
|
-
|
|
16340
|
+
if (missingFiles.length === 0 && leftoverFiles.length === 0) {
|
|
16341
|
+
const root = findTypecheckRoot(this.baseDir, existingFiles);
|
|
16342
|
+
if (root) {
|
|
16343
|
+
try {
|
|
16344
|
+
typecheckError = await runTypecheck(root);
|
|
16345
|
+
} catch {
|
|
16346
|
+
typecheckError = null;
|
|
16347
|
+
}
|
|
16131
16348
|
}
|
|
16132
16349
|
}
|
|
16133
16350
|
const doneSteps = plan.steps.filter((s) => s.status === "done").length;
|
|
@@ -16140,7 +16357,7 @@ class Auditor {
|
|
|
16140
16357
|
count: String(auditedFiles.length)
|
|
16141
16358
|
});
|
|
16142
16359
|
}
|
|
16143
|
-
const testsFailing = testRun !== null && testRun.
|
|
16360
|
+
const testsFailing = testRun !== null && !testRun.passed;
|
|
16144
16361
|
const typecheckFailing = typecheckError !== null;
|
|
16145
16362
|
const passed = missingFiles.length === 0 && leftoverFiles.length === 0 && !testsFailing && !typecheckFailing;
|
|
16146
16363
|
const stepsPending = terminalSteps < totalSteps;
|
|
@@ -16206,7 +16423,7 @@ var init_auditor = __esm(() => {
|
|
|
16206
16423
|
});
|
|
16207
16424
|
|
|
16208
16425
|
// src/modules/execution/plan-store.ts
|
|
16209
|
-
import { readFileSync as readFileSync16, writeFileSync as writeFileSync10, mkdirSync as mkdirSync14, existsSync as
|
|
16426
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync10, mkdirSync as mkdirSync14, existsSync as existsSync30, readdirSync as readdirSync10, rmSync } from "fs";
|
|
16210
16427
|
import { join as join25 } from "path";
|
|
16211
16428
|
function readPlanFile(path, fallbackBaseDir) {
|
|
16212
16429
|
try {
|
|
@@ -16232,7 +16449,7 @@ function writePlanFile(path, plan) {
|
|
|
16232
16449
|
writeFileSync10(path, JSON.stringify(plan, null, 2), "utf-8");
|
|
16233
16450
|
}
|
|
16234
16451
|
function listDir(dir, baseDir) {
|
|
16235
|
-
if (!
|
|
16452
|
+
if (!existsSync30(dir))
|
|
16236
16453
|
return [];
|
|
16237
16454
|
const files = readdirSync10(dir).filter((f) => f.endsWith(".json"));
|
|
16238
16455
|
return files.map((f) => readPlanFile(join25(dir, f), baseDir)).filter((p) => p !== null);
|
|
@@ -16257,7 +16474,7 @@ class PlanStore {
|
|
|
16257
16474
|
legacyPath;
|
|
16258
16475
|
constructor(baseDir) {
|
|
16259
16476
|
const mmaDir = join25(baseDir, ".mma");
|
|
16260
|
-
if (!
|
|
16477
|
+
if (!existsSync30(mmaDir))
|
|
16261
16478
|
mkdirSync14(mmaDir, { recursive: true });
|
|
16262
16479
|
this.baseDir = baseDir;
|
|
16263
16480
|
this.plansDir = join25(mmaDir, "plans");
|
|
@@ -16265,7 +16482,7 @@ class PlanStore {
|
|
|
16265
16482
|
this.archiveDir = join25(this.plansDir, "archive");
|
|
16266
16483
|
this.legacyPath = join25(mmaDir, LEGACY_FILE);
|
|
16267
16484
|
for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
|
|
16268
|
-
if (!
|
|
16485
|
+
if (!existsSync30(dir))
|
|
16269
16486
|
mkdirSync14(dir, { recursive: true });
|
|
16270
16487
|
}
|
|
16271
16488
|
}
|
|
@@ -16277,12 +16494,12 @@ class PlanStore {
|
|
|
16277
16494
|
}
|
|
16278
16495
|
loadActive() {
|
|
16279
16496
|
const activePath = this.activePath();
|
|
16280
|
-
if (
|
|
16497
|
+
if (existsSync30(activePath)) {
|
|
16281
16498
|
const plan = readPlanFile(activePath, this.baseDir);
|
|
16282
16499
|
if (plan)
|
|
16283
16500
|
return plan;
|
|
16284
16501
|
}
|
|
16285
|
-
if (
|
|
16502
|
+
if (existsSync30(this.legacyPath)) {
|
|
16286
16503
|
const legacy = readPlanFile(this.legacyPath, this.baseDir);
|
|
16287
16504
|
if (legacy) {
|
|
16288
16505
|
this.saveActive(legacy);
|
|
@@ -16296,7 +16513,7 @@ class PlanStore {
|
|
|
16296
16513
|
}
|
|
16297
16514
|
clearActive() {
|
|
16298
16515
|
const p = this.activePath();
|
|
16299
|
-
if (
|
|
16516
|
+
if (existsSync30(p))
|
|
16300
16517
|
rmSync(p, { force: true });
|
|
16301
16518
|
}
|
|
16302
16519
|
saveDraft(plan) {
|
|
@@ -16304,11 +16521,11 @@ class PlanStore {
|
|
|
16304
16521
|
}
|
|
16305
16522
|
loadDraft(id) {
|
|
16306
16523
|
const p = join25(this.draftsDir, `${id}.json`);
|
|
16307
|
-
return
|
|
16524
|
+
return existsSync30(p) ? readPlanFile(p, this.baseDir) : null;
|
|
16308
16525
|
}
|
|
16309
16526
|
removeDraft(id) {
|
|
16310
16527
|
const p = join25(this.draftsDir, `${id}.json`);
|
|
16311
|
-
if (
|
|
16528
|
+
if (existsSync30(p))
|
|
16312
16529
|
rmSync(p, { force: true });
|
|
16313
16530
|
}
|
|
16314
16531
|
listDrafts() {
|
|
@@ -16327,7 +16544,7 @@ class PlanStore {
|
|
|
16327
16544
|
}
|
|
16328
16545
|
removeArchived(id) {
|
|
16329
16546
|
const p = join25(this.archiveDir, `${id}.json`);
|
|
16330
|
-
if (
|
|
16547
|
+
if (existsSync30(p))
|
|
16331
16548
|
rmSync(p, { force: true });
|
|
16332
16549
|
}
|
|
16333
16550
|
listAll() {
|
|
@@ -17104,8 +17321,8 @@ var init_execution_plugin = __esm(() => {
|
|
|
17104
17321
|
});
|
|
17105
17322
|
|
|
17106
17323
|
// src/modules/execution/module.ts
|
|
17107
|
-
import { existsSync as
|
|
17108
|
-
import { resolve as
|
|
17324
|
+
import { existsSync as existsSync31, readFileSync as readFileSync17 } from "fs";
|
|
17325
|
+
import { resolve as resolve19 } from "path";
|
|
17109
17326
|
|
|
17110
17327
|
class ExecutionModule {
|
|
17111
17328
|
name = "execution";
|
|
@@ -17299,7 +17516,7 @@ class ExecutionModule {
|
|
|
17299
17516
|
"poetry.lock",
|
|
17300
17517
|
"requirements.txt"
|
|
17301
17518
|
];
|
|
17302
|
-
const hasLockFile = lockFiles.some((f) =>
|
|
17519
|
+
const hasLockFile = lockFiles.some((f) => existsSync31(resolve19(this.baseDir, f)));
|
|
17303
17520
|
if (!hasLockFile) {
|
|
17304
17521
|
if (contextManager) {
|
|
17305
17522
|
const hints = this.state.depsGateHints.get(step.id) || 0;
|
|
@@ -17319,8 +17536,8 @@ class ExecutionModule {
|
|
|
17319
17536
|
}
|
|
17320
17537
|
if (stepPaths.length === 0)
|
|
17321
17538
|
return;
|
|
17322
|
-
const allExist = stepPaths.every((p) =>
|
|
17323
|
-
const allGone = stepPaths.every((p) => !
|
|
17539
|
+
const allExist = stepPaths.every((p) => existsSync31(resolve19(this.baseDir, p)));
|
|
17540
|
+
const allGone = stepPaths.every((p) => !existsSync31(resolve19(this.baseDir, p)));
|
|
17324
17541
|
const satisfied = step.kind === "delete" ? allGone && !allExist : allExist;
|
|
17325
17542
|
if (!satisfied)
|
|
17326
17543
|
return;
|
|
@@ -17328,7 +17545,7 @@ class ExecutionModule {
|
|
|
17328
17545
|
const emptyFiles = [];
|
|
17329
17546
|
for (const p of stepPaths) {
|
|
17330
17547
|
try {
|
|
17331
|
-
const content = readFileSync17(
|
|
17548
|
+
const content = readFileSync17(resolve19(this.baseDir, p), "utf-8");
|
|
17332
17549
|
if (content.trim().length < 10) {
|
|
17333
17550
|
emptyFiles.push(p);
|
|
17334
17551
|
}
|
|
@@ -17426,7 +17643,7 @@ var init_module = __esm(() => {
|
|
|
17426
17643
|
import {
|
|
17427
17644
|
readFileSync as readFileSync18,
|
|
17428
17645
|
writeFileSync as writeFileSync11,
|
|
17429
|
-
existsSync as
|
|
17646
|
+
existsSync as existsSync32,
|
|
17430
17647
|
readdirSync as readdirSync11,
|
|
17431
17648
|
unlinkSync as unlinkSync4
|
|
17432
17649
|
} from "fs";
|
|
@@ -17526,7 +17743,7 @@ class SessionFileEncryptor {
|
|
|
17526
17743
|
const files = readdirSync11(sessionDir);
|
|
17527
17744
|
for (const file of files) {
|
|
17528
17745
|
const filePath = join26(sessionDir, file);
|
|
17529
|
-
if (
|
|
17746
|
+
if (existsSync32(filePath) && !file.endsWith(".enc")) {
|
|
17530
17747
|
try {
|
|
17531
17748
|
const content = readFileSync18(filePath, "utf8");
|
|
17532
17749
|
const encrypted = this.encryptFileContent(content);
|
|
@@ -17567,7 +17784,7 @@ var init_session_encryption = __esm(() => {
|
|
|
17567
17784
|
|
|
17568
17785
|
// src/modules/session/store.ts
|
|
17569
17786
|
import {
|
|
17570
|
-
existsSync as
|
|
17787
|
+
existsSync as existsSync33,
|
|
17571
17788
|
mkdirSync as mkdirSync15,
|
|
17572
17789
|
readdirSync as readdirSync12,
|
|
17573
17790
|
readFileSync as readFileSync19,
|
|
@@ -17617,7 +17834,7 @@ class SessionStore {
|
|
|
17617
17834
|
return join27(this.sessionDir(id), "session.jsonl");
|
|
17618
17835
|
}
|
|
17619
17836
|
sessionExists(id) {
|
|
17620
|
-
return
|
|
17837
|
+
return existsSync33(this.metaPath(id));
|
|
17621
17838
|
}
|
|
17622
17839
|
saveMeta(id, meta) {
|
|
17623
17840
|
this._metaCache.set(id, meta);
|
|
@@ -17635,7 +17852,7 @@ class SessionStore {
|
|
|
17635
17852
|
if (cached)
|
|
17636
17853
|
return cached;
|
|
17637
17854
|
const path = this.metaPath(id);
|
|
17638
|
-
if (!
|
|
17855
|
+
if (!existsSync33(path))
|
|
17639
17856
|
return null;
|
|
17640
17857
|
try {
|
|
17641
17858
|
const raw = readFileSync19(path, "utf-8");
|
|
@@ -17667,7 +17884,7 @@ class SessionStore {
|
|
|
17667
17884
|
}
|
|
17668
17885
|
loadHistory(id) {
|
|
17669
17886
|
const path = this.historyPath(id);
|
|
17670
|
-
if (!
|
|
17887
|
+
if (!existsSync33(path))
|
|
17671
17888
|
return [];
|
|
17672
17889
|
try {
|
|
17673
17890
|
const raw = readFileSync19(path, "utf-8");
|
|
@@ -17708,7 +17925,7 @@ class SessionStore {
|
|
|
17708
17925
|
}
|
|
17709
17926
|
loadSessionLog(id) {
|
|
17710
17927
|
const path = this.sessionLogPath(id);
|
|
17711
|
-
if (!
|
|
17928
|
+
if (!existsSync33(path))
|
|
17712
17929
|
return [];
|
|
17713
17930
|
try {
|
|
17714
17931
|
const raw = readFileSync19(path, "utf-8");
|
|
@@ -17736,7 +17953,7 @@ class SessionStore {
|
|
|
17736
17953
|
}
|
|
17737
17954
|
}
|
|
17738
17955
|
listSessions() {
|
|
17739
|
-
if (!
|
|
17956
|
+
if (!existsSync33(this.baseDir))
|
|
17740
17957
|
return [];
|
|
17741
17958
|
const entries = readdirSync12(this.baseDir, { withFileTypes: true });
|
|
17742
17959
|
const sessions = [];
|
|
@@ -17753,7 +17970,7 @@ class SessionStore {
|
|
|
17753
17970
|
deleteSession(id) {
|
|
17754
17971
|
this._metaCache.delete(id);
|
|
17755
17972
|
const dir = this.sessionDir(id);
|
|
17756
|
-
if (
|
|
17973
|
+
if (existsSync33(dir)) {
|
|
17757
17974
|
rmSync2(dir, { recursive: true, force: true });
|
|
17758
17975
|
}
|
|
17759
17976
|
}
|
|
@@ -17765,7 +17982,7 @@ class SessionStore {
|
|
|
17765
17982
|
const updatedAt = new Date(session2.updatedAt);
|
|
17766
17983
|
if (updatedAt < thirtyDaysAgo) {
|
|
17767
17984
|
const historyPath = this.historyPath(session2.id);
|
|
17768
|
-
if (
|
|
17985
|
+
if (existsSync33(historyPath)) {
|
|
17769
17986
|
const content = readFileSync19(historyPath, "utf-8");
|
|
17770
17987
|
const compressed = gzipSync(content);
|
|
17771
17988
|
const gzPath = join27(this.baseDir, `${session2.id}.jsonl.gz`);
|
|
@@ -17978,7 +18195,7 @@ class ProfileCompressor {
|
|
|
17978
18195
|
}
|
|
17979
18196
|
|
|
17980
18197
|
// src/modules/user-profile/profile.ts
|
|
17981
|
-
import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, existsSync as
|
|
18198
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, existsSync as existsSync34, mkdirSync as mkdirSync16 } from "fs";
|
|
17982
18199
|
import { join as join28 } from "path";
|
|
17983
18200
|
import { homedir as homedir9, hostname, platform as platform5, type } from "os";
|
|
17984
18201
|
import { env } from "process";
|
|
@@ -18003,14 +18220,14 @@ class UserProfile {
|
|
|
18003
18220
|
return this.info;
|
|
18004
18221
|
}
|
|
18005
18222
|
save() {
|
|
18006
|
-
if (!
|
|
18223
|
+
if (!existsSync34(this.profileDir)) {
|
|
18007
18224
|
mkdirSync16(this.profileDir, { recursive: true });
|
|
18008
18225
|
}
|
|
18009
18226
|
writeFileSync13(join28(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
|
|
18010
18227
|
}
|
|
18011
18228
|
load() {
|
|
18012
18229
|
const path = join28(this.profileDir, "profile.json");
|
|
18013
|
-
if (!
|
|
18230
|
+
if (!existsSync34(path))
|
|
18014
18231
|
return null;
|
|
18015
18232
|
try {
|
|
18016
18233
|
const data = JSON.parse(readFileSync20(path, "utf-8"));
|
|
@@ -18048,12 +18265,12 @@ class UserProfile {
|
|
|
18048
18265
|
var init_profile = () => {};
|
|
18049
18266
|
|
|
18050
18267
|
// src/modules/skills/loader.ts
|
|
18051
|
-
import { readdirSync as readdirSync13, readFileSync as readFileSync21, existsSync as
|
|
18268
|
+
import { readdirSync as readdirSync13, readFileSync as readFileSync21, existsSync as existsSync35, statSync as statSync6 } from "fs";
|
|
18052
18269
|
import { join as join29 } from "path";
|
|
18053
18270
|
|
|
18054
18271
|
class SkillsLoader {
|
|
18055
18272
|
loadFromDir(dirPath) {
|
|
18056
|
-
if (!
|
|
18273
|
+
if (!existsSync35(dirPath))
|
|
18057
18274
|
return [];
|
|
18058
18275
|
const skills = [];
|
|
18059
18276
|
this.scanDir(dirPath, skills);
|
|
@@ -18307,7 +18524,7 @@ var init_browser2 = __esm(() => {
|
|
|
18307
18524
|
|
|
18308
18525
|
// src/modules/lsp/command.ts
|
|
18309
18526
|
import { delimiter, join as join30 } from "path";
|
|
18310
|
-
import { existsSync as
|
|
18527
|
+
import { existsSync as existsSync36 } from "fs";
|
|
18311
18528
|
import { platform as platform6 } from "os";
|
|
18312
18529
|
function resolveSpawnCommand(command, platformName = platform6(), pathEnv = process.env.PATH ?? "") {
|
|
18313
18530
|
if (platformName !== "win32")
|
|
@@ -18319,7 +18536,7 @@ function resolveSpawnCommand(command, platformName = platform6(), pathEnv = proc
|
|
|
18319
18536
|
for (const dir of dirs) {
|
|
18320
18537
|
for (const ext of WIN_EXTS) {
|
|
18321
18538
|
const candidate = join30(dir, `${command}${ext}`);
|
|
18322
|
-
if (
|
|
18539
|
+
if (existsSync36(candidate))
|
|
18323
18540
|
return `${command}${ext}`;
|
|
18324
18541
|
}
|
|
18325
18542
|
}
|
|
@@ -18341,11 +18558,8 @@ var init_command = __esm(() => {
|
|
|
18341
18558
|
});
|
|
18342
18559
|
|
|
18343
18560
|
// src/modules/lsp/client.ts
|
|
18344
|
-
import {
|
|
18345
|
-
|
|
18346
|
-
execSync as execSync2
|
|
18347
|
-
} from "child_process";
|
|
18348
|
-
import { resolve as resolve19 } from "path";
|
|
18561
|
+
import { spawn as spawn6, execSync as execSync2 } from "child_process";
|
|
18562
|
+
import { resolve as resolve20 } from "path";
|
|
18349
18563
|
import { platform as platform7 } from "os";
|
|
18350
18564
|
|
|
18351
18565
|
class LspClient {
|
|
@@ -18363,25 +18577,32 @@ class LspClient {
|
|
|
18363
18577
|
try {
|
|
18364
18578
|
await this.startServer(config, projectRoot);
|
|
18365
18579
|
const rootUri = this.pathToUri(projectRoot);
|
|
18366
|
-
const
|
|
18580
|
+
const initParams = {
|
|
18367
18581
|
processId: process.pid,
|
|
18368
18582
|
rootUri,
|
|
18369
18583
|
workspaceFolders: [{ uri: rootUri, name: "workspace" }],
|
|
18370
18584
|
capabilities: { textDocument: { publishDiagnostics: {} } }
|
|
18371
|
-
}
|
|
18585
|
+
};
|
|
18586
|
+
try {
|
|
18587
|
+
await this.sendRequest("initialize", initParams, timeout);
|
|
18588
|
+
} catch (e) {
|
|
18589
|
+
if (!(e instanceof Error) || !e.message.includes("initialize"))
|
|
18590
|
+
throw e;
|
|
18591
|
+
await this.shutdown();
|
|
18592
|
+
await this.startServer(config, projectRoot);
|
|
18593
|
+
await this.sendRequest("initialize", initParams, timeout);
|
|
18594
|
+
}
|
|
18372
18595
|
this.initialized = true;
|
|
18373
18596
|
this.sendNotification("initialized", {});
|
|
18374
|
-
const uri = this.pathToUri(
|
|
18597
|
+
const uri = this.pathToUri(resolve20(filePath));
|
|
18375
18598
|
const fs2 = await import("fs");
|
|
18376
18599
|
const content = fs2.readFileSync(filePath, "utf-8");
|
|
18377
|
-
const diagPromise = new Promise((
|
|
18378
|
-
this.diagnosticsResolve =
|
|
18600
|
+
const diagPromise = new Promise((resolve21) => {
|
|
18601
|
+
this.diagnosticsResolve = resolve21;
|
|
18379
18602
|
this.diagnostics = [];
|
|
18380
18603
|
this.diagnosticsTimer = setTimeout(() => {
|
|
18381
|
-
|
|
18382
|
-
|
|
18383
|
-
this.diagnosticsResolve = null;
|
|
18384
|
-
}
|
|
18604
|
+
this.diagnosticsResolve?.([]);
|
|
18605
|
+
this.diagnosticsResolve = null;
|
|
18385
18606
|
}, timeout);
|
|
18386
18607
|
});
|
|
18387
18608
|
this.sendNotification("textDocument/didOpen", {
|
|
@@ -18407,7 +18628,7 @@ class LspClient {
|
|
|
18407
18628
|
throw new Error(`${config.command} not found in PATH`);
|
|
18408
18629
|
}
|
|
18409
18630
|
}
|
|
18410
|
-
return new Promise((
|
|
18631
|
+
return new Promise((resolve21, reject) => {
|
|
18411
18632
|
const args = config.args ?? [];
|
|
18412
18633
|
const isWin = platform7() === "win32";
|
|
18413
18634
|
let spawnCommand = resolveSpawnCommand(config.command);
|
|
@@ -18429,13 +18650,12 @@ class LspClient {
|
|
|
18429
18650
|
});
|
|
18430
18651
|
proc.stderr.on("data", () => {});
|
|
18431
18652
|
proc.once("spawn", () => {
|
|
18432
|
-
|
|
18653
|
+
resolve21();
|
|
18433
18654
|
});
|
|
18434
18655
|
this.process = proc;
|
|
18435
18656
|
setTimeout(() => {
|
|
18436
|
-
if (!this.initialized && this.process)
|
|
18657
|
+
if (!this.initialized && this.process)
|
|
18437
18658
|
reject(new Error("LSP server start timeout"));
|
|
18438
|
-
}
|
|
18439
18659
|
}, config.timeout ?? 1e4);
|
|
18440
18660
|
});
|
|
18441
18661
|
}
|
|
@@ -18486,10 +18706,8 @@ class LspClient {
|
|
|
18486
18706
|
clearTimeout(this.diagnosticsTimer);
|
|
18487
18707
|
this.diagnosticsTimer = null;
|
|
18488
18708
|
}
|
|
18489
|
-
|
|
18490
|
-
|
|
18491
|
-
this.diagnosticsResolve = null;
|
|
18492
|
-
}
|
|
18709
|
+
this.diagnosticsResolve?.(this.diagnostics);
|
|
18710
|
+
this.diagnosticsResolve = null;
|
|
18493
18711
|
}
|
|
18494
18712
|
return;
|
|
18495
18713
|
}
|
|
@@ -18506,9 +18724,9 @@ class LspClient {
|
|
|
18506
18724
|
}
|
|
18507
18725
|
}
|
|
18508
18726
|
sendRequest(method, params, timeout) {
|
|
18509
|
-
return new Promise((
|
|
18727
|
+
return new Promise((resolve21, reject) => {
|
|
18510
18728
|
const id = ++this.requestId;
|
|
18511
|
-
this.pending.set(id, { resolve:
|
|
18729
|
+
this.pending.set(id, { resolve: resolve21, reject });
|
|
18512
18730
|
const message = JSON.stringify({ jsonrpc: "2.0", id, method, params });
|
|
18513
18731
|
this.write(message);
|
|
18514
18732
|
setTimeout(() => {
|
|
@@ -18548,6 +18766,8 @@ class LspClient {
|
|
|
18548
18766
|
this.process = null;
|
|
18549
18767
|
}
|
|
18550
18768
|
this.initialized = false;
|
|
18769
|
+
this.buffer = "";
|
|
18770
|
+
this.contentLength = -1;
|
|
18551
18771
|
if (this.diagnosticsTimer) {
|
|
18552
18772
|
clearTimeout(this.diagnosticsTimer);
|
|
18553
18773
|
this.diagnosticsTimer = null;
|
|
@@ -18556,10 +18776,7 @@ class LspClient {
|
|
|
18556
18776
|
}
|
|
18557
18777
|
pathToUri(filePath) {
|
|
18558
18778
|
const normalized = filePath.replace(/\\/g, "/");
|
|
18559
|
-
|
|
18560
|
-
return `file:///${normalized}`;
|
|
18561
|
-
}
|
|
18562
|
-
return `file://${normalized}`;
|
|
18779
|
+
return /^[a-zA-Z]:/.test(normalized) ? `file:///${normalized}` : `file://${normalized}`;
|
|
18563
18780
|
}
|
|
18564
18781
|
languageFromPath(filePath) {
|
|
18565
18782
|
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
@@ -18588,20 +18805,26 @@ var init_client2 = __esm(() => {
|
|
|
18588
18805
|
});
|
|
18589
18806
|
|
|
18590
18807
|
// src/modules/lsp/module.ts
|
|
18591
|
-
import { existsSync as
|
|
18592
|
-
import { resolve as
|
|
18808
|
+
import { existsSync as existsSync37 } from "fs";
|
|
18809
|
+
import { resolve as resolve21 } from "path";
|
|
18593
18810
|
|
|
18594
18811
|
class LspModule {
|
|
18595
18812
|
name = "lsp";
|
|
18596
18813
|
config;
|
|
18597
18814
|
client = new LspClient;
|
|
18598
|
-
|
|
18599
|
-
|
|
18815
|
+
failuresByServer = new Map;
|
|
18816
|
+
disabledServers = new Set;
|
|
18600
18817
|
constructor(config) {
|
|
18601
18818
|
this.config = { ...DEFAULT_LSP_CONFIG, ...config };
|
|
18602
18819
|
}
|
|
18603
18820
|
isLspDisabled() {
|
|
18604
|
-
return this.
|
|
18821
|
+
return this.disabledServers.size > 0;
|
|
18822
|
+
}
|
|
18823
|
+
isServerDisabled(key) {
|
|
18824
|
+
return this.disabledServers.has(key);
|
|
18825
|
+
}
|
|
18826
|
+
serverKey(server) {
|
|
18827
|
+
return `${server.command}:${(server.args ?? []).join(" ")}`;
|
|
18605
18828
|
}
|
|
18606
18829
|
getPlugin() {
|
|
18607
18830
|
const self = this;
|
|
@@ -18611,8 +18834,6 @@ class LspModule {
|
|
|
18611
18834
|
onAfterTool: async (_ctx, call, result) => {
|
|
18612
18835
|
if (!self.config.enabled)
|
|
18613
18836
|
return;
|
|
18614
|
-
if (self.lspDisabled)
|
|
18615
|
-
return;
|
|
18616
18837
|
if (call.name !== "write_file" && call.name !== "edit_file")
|
|
18617
18838
|
return;
|
|
18618
18839
|
if (!result.success)
|
|
@@ -18620,16 +18841,19 @@ class LspModule {
|
|
|
18620
18841
|
const filePath = String(call.arguments.path ?? "");
|
|
18621
18842
|
if (!filePath)
|
|
18622
18843
|
return;
|
|
18623
|
-
const fullPath =
|
|
18624
|
-
if (!
|
|
18844
|
+
const fullPath = resolve21(_ctx.baseDir, filePath);
|
|
18845
|
+
if (!existsSync37(fullPath))
|
|
18625
18846
|
return;
|
|
18626
18847
|
const serverConfig = getServerForFile(fullPath, self.config);
|
|
18627
18848
|
if (!serverConfig)
|
|
18628
18849
|
return;
|
|
18850
|
+
const key = self.serverKey(serverConfig);
|
|
18851
|
+
if (self.disabledServers.has(key))
|
|
18852
|
+
return;
|
|
18629
18853
|
const projectRoot = findProjectRoot(fullPath, _ctx.baseDir, serverConfig.workspaceMarkers ?? []);
|
|
18630
18854
|
try {
|
|
18631
18855
|
const diagnostics = await self.client.checkFile(fullPath, _ctx.baseDir, serverConfig, projectRoot);
|
|
18632
|
-
self.
|
|
18856
|
+
self.failuresByServer.set(key, 0);
|
|
18633
18857
|
const errors = diagnostics.filter((d) => d.severity === 1);
|
|
18634
18858
|
const warnings = diagnostics.filter((d) => d.severity === 2);
|
|
18635
18859
|
if (errors.length > 0) {
|
|
@@ -18648,12 +18872,13 @@ ${items}`;
|
|
|
18648
18872
|
}
|
|
18649
18873
|
} catch (e) {
|
|
18650
18874
|
const msg = e instanceof Error ? e.message : String(e);
|
|
18651
|
-
self.
|
|
18875
|
+
const failures = (self.failuresByServer.get(key) ?? 0) + 1;
|
|
18876
|
+
self.failuresByServer.set(key, failures);
|
|
18652
18877
|
try {
|
|
18653
18878
|
_ctx.logger?.warn(`LSP check failed for ${filePath}: ${msg}`);
|
|
18654
18879
|
} catch {}
|
|
18655
|
-
if (
|
|
18656
|
-
self.
|
|
18880
|
+
if (failures >= MAX_CONSECUTIVE_LSP_FAILURES) {
|
|
18881
|
+
self.disabledServers.add(key);
|
|
18657
18882
|
result.output += `
|
|
18658
18883
|
|
|
18659
18884
|
[LSP disabled: ${t("lsp.unavailable")}]`;
|
|
@@ -18699,7 +18924,7 @@ var init_lsp = __esm(() => {
|
|
|
18699
18924
|
});
|
|
18700
18925
|
|
|
18701
18926
|
// src/modules/indexer/walker.ts
|
|
18702
|
-
import { readdirSync as readdirSync14, readFileSync as readFileSync22, statSync as statSync7, existsSync as
|
|
18927
|
+
import { readdirSync as readdirSync14, readFileSync as readFileSync22, statSync as statSync7, existsSync as existsSync38, watch } from "fs";
|
|
18703
18928
|
import { join as join31, relative as relative2, extname as extname5 } from "path";
|
|
18704
18929
|
|
|
18705
18930
|
class Indexer {
|
|
@@ -18727,7 +18952,7 @@ class Indexer {
|
|
|
18727
18952
|
let totalSize = 0;
|
|
18728
18953
|
let count = 0;
|
|
18729
18954
|
const walkDir = (dir) => {
|
|
18730
|
-
if (!
|
|
18955
|
+
if (!existsSync38(dir))
|
|
18731
18956
|
return;
|
|
18732
18957
|
let entries;
|
|
18733
18958
|
try {
|
|
@@ -18801,7 +19026,7 @@ var init_walker = __esm(() => {
|
|
|
18801
19026
|
});
|
|
18802
19027
|
|
|
18803
19028
|
// src/modules/indexer/cache.ts
|
|
18804
|
-
import { readFileSync as readFileSync23, writeFileSync as writeFileSync14, existsSync as
|
|
19029
|
+
import { readFileSync as readFileSync23, writeFileSync as writeFileSync14, existsSync as existsSync39, mkdirSync as mkdirSync17, rmSync as rmSync3 } from "fs";
|
|
18805
19030
|
import { join as join32 } from "path";
|
|
18806
19031
|
|
|
18807
19032
|
class IndexCache {
|
|
@@ -18813,7 +19038,7 @@ class IndexCache {
|
|
|
18813
19038
|
load() {
|
|
18814
19039
|
if (this.cache)
|
|
18815
19040
|
return this.cache;
|
|
18816
|
-
if (!
|
|
19041
|
+
if (!existsSync39(this.cachePath))
|
|
18817
19042
|
return null;
|
|
18818
19043
|
try {
|
|
18819
19044
|
this.cache = JSON.parse(readFileSync23(this.cachePath, "utf-8"));
|
|
@@ -18825,13 +19050,13 @@ class IndexCache {
|
|
|
18825
19050
|
save(result) {
|
|
18826
19051
|
this.cache = result;
|
|
18827
19052
|
const dir = join32(this.cachePath, "..");
|
|
18828
|
-
if (!
|
|
19053
|
+
if (!existsSync39(dir))
|
|
18829
19054
|
mkdirSync17(dir, { recursive: true });
|
|
18830
19055
|
writeFileSync14(this.cachePath, JSON.stringify(result), "utf-8");
|
|
18831
19056
|
}
|
|
18832
19057
|
invalidate() {
|
|
18833
19058
|
this.cache = null;
|
|
18834
|
-
if (
|
|
19059
|
+
if (existsSync39(this.cachePath)) {
|
|
18835
19060
|
try {
|
|
18836
19061
|
rmSync3(this.cachePath);
|
|
18837
19062
|
} catch {}
|
|
@@ -18841,11 +19066,11 @@ class IndexCache {
|
|
|
18841
19066
|
var init_cache = () => {};
|
|
18842
19067
|
|
|
18843
19068
|
// src/modules/indexer/project-profile.ts
|
|
18844
|
-
import { readFileSync as readFileSync24, existsSync as
|
|
19069
|
+
import { readFileSync as readFileSync24, existsSync as existsSync40 } from "fs";
|
|
18845
19070
|
import { join as join33 } from "path";
|
|
18846
19071
|
function detectManifest(baseDir) {
|
|
18847
19072
|
for (const manifest of MANIFEST_ORDER) {
|
|
18848
|
-
if (
|
|
19073
|
+
if (existsSync40(join33(baseDir, manifest)))
|
|
18849
19074
|
return manifest;
|
|
18850
19075
|
}
|
|
18851
19076
|
return null;
|
|
@@ -19009,7 +19234,7 @@ var init_project_profile = __esm(() => {
|
|
|
19009
19234
|
});
|
|
19010
19235
|
|
|
19011
19236
|
// src/modules/indexer/module.ts
|
|
19012
|
-
import { dirname as
|
|
19237
|
+
import { dirname as dirname12 } from "path";
|
|
19013
19238
|
|
|
19014
19239
|
class IndexerModule {
|
|
19015
19240
|
name = "indexer";
|
|
@@ -19160,7 +19385,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
|
19160
19385
|
const counts = {};
|
|
19161
19386
|
for (const f of result.files) {
|
|
19162
19387
|
const normalized = f.path.replace(/\\/g, "/");
|
|
19163
|
-
const dir =
|
|
19388
|
+
const dir = dirname12(normalized);
|
|
19164
19389
|
const key = dir === "." ? "(root)" : dir;
|
|
19165
19390
|
counts[key] = (counts[key] || 0) + 1;
|
|
19166
19391
|
}
|
|
@@ -19499,8 +19724,8 @@ __export(exports_bootstrap, {
|
|
|
19499
19724
|
bootstrap: () => bootstrap
|
|
19500
19725
|
});
|
|
19501
19726
|
import { homedir as homedir11 } from "os";
|
|
19502
|
-
import { join as join35, resolve as
|
|
19503
|
-
import { existsSync as
|
|
19727
|
+
import { join as join35, resolve as resolve22 } from "path";
|
|
19728
|
+
import { existsSync as existsSync41, readFileSync as readFileSync25, writeFileSync as writeFileSync15 } from "fs";
|
|
19504
19729
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
19505
19730
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
19506
19731
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -19570,7 +19795,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19570
19795
|
retry: config.retry,
|
|
19571
19796
|
rateLimits: config.security?.rateLimits
|
|
19572
19797
|
});
|
|
19573
|
-
const baseDir = projectDir ?
|
|
19798
|
+
const baseDir = projectDir ? resolve22(projectDir) : process.cwd();
|
|
19574
19799
|
const projectMapCacheDir = join35(baseDir, ".mma");
|
|
19575
19800
|
const indexerModule = new IndexerModule({
|
|
19576
19801
|
baseDir,
|
|
@@ -19599,7 +19824,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19599
19824
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
19600
19825
|
};
|
|
19601
19826
|
const agentsMdGlobal = join35(dir, "AGENTS.md");
|
|
19602
|
-
if (!
|
|
19827
|
+
if (!existsSync41(agentsMdGlobal)) {
|
|
19603
19828
|
writeFileSync15(agentsMdGlobal, "", "utf-8");
|
|
19604
19829
|
}
|
|
19605
19830
|
const sessionDir = join35(dir, "sessions");
|
|
@@ -19744,7 +19969,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19744
19969
|
join35(dir, "AGENTS.md")
|
|
19745
19970
|
];
|
|
19746
19971
|
for (const p of agentsMdCandidates) {
|
|
19747
|
-
if (
|
|
19972
|
+
if (existsSync41(p)) {
|
|
19748
19973
|
const content = readFileSync25(p, "utf-8").trim();
|
|
19749
19974
|
if (content) {
|
|
19750
19975
|
agentsMdBlocks.push({
|
|
@@ -20377,10 +20602,10 @@ function menuList(items) {
|
|
|
20377
20602
|
console.log(l);
|
|
20378
20603
|
}
|
|
20379
20604
|
function ask(rl, question, defaultValue) {
|
|
20380
|
-
return new Promise((
|
|
20605
|
+
return new Promise((resolve23) => {
|
|
20381
20606
|
const prompt = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
20382
20607
|
rl.question(prompt, (answer) => {
|
|
20383
|
-
|
|
20608
|
+
resolve23(answer.trim() || defaultValue || "");
|
|
20384
20609
|
});
|
|
20385
20610
|
});
|
|
20386
20611
|
}
|
|
@@ -20599,12 +20824,12 @@ __export(exports_manifest, {
|
|
|
20599
20824
|
getCertMark: () => getCertMark,
|
|
20600
20825
|
MANIFEST_PATH: () => MANIFEST_PATH
|
|
20601
20826
|
});
|
|
20602
|
-
import { existsSync as
|
|
20827
|
+
import { existsSync as existsSync42, readFileSync as readFileSync26, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
20603
20828
|
import { homedir as homedir13 } from "os";
|
|
20604
20829
|
import { join as join37 } from "path";
|
|
20605
20830
|
function readManifest(path = MANIFEST_PATH) {
|
|
20606
20831
|
try {
|
|
20607
|
-
if (
|
|
20832
|
+
if (existsSync42(path)) {
|
|
20608
20833
|
const raw = JSON.parse(readFileSync26(path, "utf-8"));
|
|
20609
20834
|
return { version: 1, certifications: raw.certifications ?? [] };
|
|
20610
20835
|
}
|
|
@@ -27770,7 +27995,7 @@ var init_scenarios = __esm(() => {
|
|
|
27770
27995
|
});
|
|
27771
27996
|
|
|
27772
27997
|
// src/modules/certification/loader.ts
|
|
27773
|
-
import { existsSync as
|
|
27998
|
+
import { existsSync as existsSync43, readdirSync as readdirSync15, readFileSync as readFileSync27 } from "fs";
|
|
27774
27999
|
import { join as join38 } from "path";
|
|
27775
28000
|
function validateScenario(s) {
|
|
27776
28001
|
const errors2 = [];
|
|
@@ -27820,7 +28045,7 @@ function loadScenarios(userDir) {
|
|
|
27820
28045
|
else
|
|
27821
28046
|
scenarios.push(s);
|
|
27822
28047
|
}
|
|
27823
|
-
if (userDir &&
|
|
28048
|
+
if (userDir && existsSync43(userDir)) {
|
|
27824
28049
|
for (const file of readdirSync15(userDir)) {
|
|
27825
28050
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
27826
28051
|
continue;
|
|
@@ -27878,7 +28103,7 @@ var init_loader3 = __esm(() => {
|
|
|
27878
28103
|
});
|
|
27879
28104
|
|
|
27880
28105
|
// src/modules/certification/fact-checker.ts
|
|
27881
|
-
import { existsSync as
|
|
28106
|
+
import { existsSync as existsSync44, readFileSync as readFileSync28, statSync as statSync8 } from "fs";
|
|
27882
28107
|
import { join as join39 } from "path";
|
|
27883
28108
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
27884
28109
|
const failures = [];
|
|
@@ -27898,7 +28123,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
27898
28123
|
case "fileExists":
|
|
27899
28124
|
return isFile(join39(sandboxDir, check.path));
|
|
27900
28125
|
case "fileNotExists":
|
|
27901
|
-
return !
|
|
28126
|
+
return !existsSync44(join39(sandboxDir, check.path));
|
|
27902
28127
|
case "dirExists":
|
|
27903
28128
|
return isDir(join39(sandboxDir, check.path));
|
|
27904
28129
|
case "fileContent": {
|
|
@@ -27924,14 +28149,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
27924
28149
|
}
|
|
27925
28150
|
function isFile(p) {
|
|
27926
28151
|
try {
|
|
27927
|
-
return
|
|
28152
|
+
return existsSync44(p) && statSync8(p).isFile();
|
|
27928
28153
|
} catch {
|
|
27929
28154
|
return false;
|
|
27930
28155
|
}
|
|
27931
28156
|
}
|
|
27932
28157
|
function isDir(p) {
|
|
27933
28158
|
try {
|
|
27934
|
-
return
|
|
28159
|
+
return existsSync44(p) && statSync8(p).isDirectory();
|
|
27935
28160
|
} catch {
|
|
27936
28161
|
return false;
|
|
27937
28162
|
}
|
|
@@ -27962,9 +28187,9 @@ var init_fact_checker = () => {};
|
|
|
27962
28187
|
|
|
27963
28188
|
// src/modules/certification/runner.ts
|
|
27964
28189
|
import { spawn as spawn7 } from "child_process";
|
|
27965
|
-
import { existsSync as
|
|
28190
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync19, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
|
|
27966
28191
|
import { platform as platform8 } from "os";
|
|
27967
|
-
import { join as join40, resolve as
|
|
28192
|
+
import { join as join40, resolve as resolve23, dirname as dirname13 } from "path";
|
|
27968
28193
|
async function runScenario(scenario, opts) {
|
|
27969
28194
|
if (scenario.mode === "skip") {
|
|
27970
28195
|
return {
|
|
@@ -28045,27 +28270,27 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
|
28045
28270
|
mkdirSync19(sandbox, { recursive: true });
|
|
28046
28271
|
for (const f of scenario.fixtures ?? []) {
|
|
28047
28272
|
const src = join40(mmaRoot, f.source);
|
|
28048
|
-
if (!
|
|
28273
|
+
if (!existsSync45(src)) {
|
|
28049
28274
|
throw new Error(`fixture missing: ${f.source}`);
|
|
28050
28275
|
}
|
|
28051
28276
|
const dest = join40(sandbox, f.dest);
|
|
28052
|
-
mkdirSync19(
|
|
28277
|
+
mkdirSync19(dirname13(dest), { recursive: true });
|
|
28053
28278
|
cpSync2(src, dest);
|
|
28054
28279
|
}
|
|
28055
28280
|
}
|
|
28056
28281
|
function resolveMmaEntry(mmaRoot) {
|
|
28057
28282
|
const dev = join40(mmaRoot, "src", "cli", "main.ts");
|
|
28058
|
-
if (
|
|
28283
|
+
if (existsSync45(dev))
|
|
28059
28284
|
return dev;
|
|
28060
28285
|
return join40(mmaRoot, "dist", "main.js");
|
|
28061
28286
|
}
|
|
28062
28287
|
function findMmaRoot(fromDir) {
|
|
28063
28288
|
const candidates = [
|
|
28064
|
-
|
|
28065
|
-
|
|
28289
|
+
resolve23(fromDir, "..", "..", ".."),
|
|
28290
|
+
resolve23(fromDir, "..")
|
|
28066
28291
|
];
|
|
28067
28292
|
for (const c of candidates) {
|
|
28068
|
-
if (
|
|
28293
|
+
if (existsSync45(join40(c, "package.json")))
|
|
28069
28294
|
return c;
|
|
28070
28295
|
}
|
|
28071
28296
|
return process.cwd();
|
|
@@ -28133,13 +28358,13 @@ __export(exports_cli, {
|
|
|
28133
28358
|
});
|
|
28134
28359
|
import { rmSync as rmSync5 } from "fs";
|
|
28135
28360
|
import { homedir as homedir14 } from "os";
|
|
28136
|
-
import { join as join41, dirname as
|
|
28361
|
+
import { join as join41, dirname as dirname14 } from "path";
|
|
28137
28362
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
28138
|
-
import { existsSync as
|
|
28363
|
+
import { existsSync as existsSync46, readFileSync as readFileSync29 } from "fs";
|
|
28139
28364
|
function readVersion() {
|
|
28140
28365
|
const candidates = [join41(MMA_ROOT, "package.json")];
|
|
28141
28366
|
for (const p of candidates) {
|
|
28142
|
-
if (
|
|
28367
|
+
if (existsSync46(p)) {
|
|
28143
28368
|
try {
|
|
28144
28369
|
const raw = JSON.parse(readFileSync29(p, "utf-8"));
|
|
28145
28370
|
if (raw.version)
|
|
@@ -28289,7 +28514,7 @@ var init_cli = __esm(() => {
|
|
|
28289
28514
|
init_loader3();
|
|
28290
28515
|
init_runner2();
|
|
28291
28516
|
init_manifest();
|
|
28292
|
-
HERE =
|
|
28517
|
+
HERE = dirname14(fileURLToPath2(import.meta.url));
|
|
28293
28518
|
MMA_ROOT = findMmaRoot(HERE);
|
|
28294
28519
|
USER_SCENARIO_DIR = join41(homedir14(), ".mma", "certification", "scenarios");
|
|
28295
28520
|
});
|
|
@@ -28300,18 +28525,18 @@ __export(exports_repl_commands, {
|
|
|
28300
28525
|
registerAllCommands: () => registerAllCommands,
|
|
28301
28526
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
28302
28527
|
});
|
|
28303
|
-
import { join as join43, dirname as
|
|
28528
|
+
import { join as join43, dirname as dirname16 } from "path";
|
|
28304
28529
|
import { homedir as homedir16 } from "os";
|
|
28305
|
-
import { existsSync as
|
|
28530
|
+
import { existsSync as existsSync48, readFileSync as readFileSync31 } from "fs";
|
|
28306
28531
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
28307
28532
|
function readVersion3() {
|
|
28308
|
-
const here =
|
|
28533
|
+
const here = dirname16(fileURLToPath4(import.meta.url));
|
|
28309
28534
|
const candidates = [
|
|
28310
28535
|
join43(here, "..", "..", "package.json"),
|
|
28311
28536
|
join43(here, "..", "package.json")
|
|
28312
28537
|
];
|
|
28313
28538
|
for (const p of candidates) {
|
|
28314
|
-
if (
|
|
28539
|
+
if (existsSync48(p)) {
|
|
28315
28540
|
try {
|
|
28316
28541
|
const raw = JSON.parse(readFileSync31(p, "utf8"));
|
|
28317
28542
|
if (raw.version)
|
|
@@ -28377,8 +28602,8 @@ function registerMmaCommands(ctx) {
|
|
|
28377
28602
|
}
|
|
28378
28603
|
try {
|
|
28379
28604
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
28380
|
-
const { existsSync:
|
|
28381
|
-
const { resolve:
|
|
28605
|
+
const { existsSync: existsSync49 } = await import("fs");
|
|
28606
|
+
const { resolve: resolve24 } = await import("path");
|
|
28382
28607
|
let dataUrl;
|
|
28383
28608
|
let label;
|
|
28384
28609
|
if (source.toLowerCase() === "clipboard") {
|
|
@@ -28396,8 +28621,8 @@ function registerMmaCommands(ctx) {
|
|
|
28396
28621
|
dataUrl = result.dataUrl;
|
|
28397
28622
|
label = source;
|
|
28398
28623
|
} else {
|
|
28399
|
-
const absPath =
|
|
28400
|
-
if (!
|
|
28624
|
+
const absPath = resolve24(process.cwd(), source);
|
|
28625
|
+
if (!existsSync49(absPath)) {
|
|
28401
28626
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
28402
28627
|
return;
|
|
28403
28628
|
}
|
|
@@ -28933,9 +29158,9 @@ init_bootstrap();
|
|
|
28933
29158
|
init_config2();
|
|
28934
29159
|
init_setup();
|
|
28935
29160
|
init_i18n();
|
|
28936
|
-
import { join as join42, dirname as
|
|
29161
|
+
import { join as join42, dirname as dirname15 } from "path";
|
|
28937
29162
|
import { homedir as homedir15 } from "os";
|
|
28938
|
-
import { existsSync as
|
|
29163
|
+
import { existsSync as existsSync47, readFileSync as readFileSync30 } from "fs";
|
|
28939
29164
|
|
|
28940
29165
|
// src/cli/security-commands.ts
|
|
28941
29166
|
init_bootstrap();
|
|
@@ -29557,13 +29782,13 @@ function createSecurityCommand(program2) {
|
|
|
29557
29782
|
// src/cli/commands.ts
|
|
29558
29783
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
29559
29784
|
function readVersion2() {
|
|
29560
|
-
const here =
|
|
29785
|
+
const here = dirname15(fileURLToPath3(import.meta.url));
|
|
29561
29786
|
const candidates = [
|
|
29562
29787
|
join42(here, "..", "..", "package.json"),
|
|
29563
29788
|
join42(here, "..", "package.json")
|
|
29564
29789
|
];
|
|
29565
29790
|
for (const p of candidates) {
|
|
29566
|
-
if (
|
|
29791
|
+
if (existsSync47(p)) {
|
|
29567
29792
|
try {
|
|
29568
29793
|
const raw = JSON.parse(readFileSync30(p, "utf8"));
|
|
29569
29794
|
if (raw.version)
|
|
@@ -30510,8 +30735,8 @@ class LineEditor {
|
|
|
30510
30735
|
}
|
|
30511
30736
|
|
|
30512
30737
|
// src/cli/repl.ts
|
|
30513
|
-
import { existsSync as
|
|
30514
|
-
import { join as join44, dirname as
|
|
30738
|
+
import { existsSync as existsSync49, readFileSync as readFileSync32, writeFileSync as writeFileSync17 } from "fs";
|
|
30739
|
+
import { join as join44, dirname as dirname17 } from "path";
|
|
30515
30740
|
import { homedir as homedir17 } from "os";
|
|
30516
30741
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
30517
30742
|
|
|
@@ -31015,13 +31240,13 @@ init_box();
|
|
|
31015
31240
|
init_i18n();
|
|
31016
31241
|
init_repl_commands();
|
|
31017
31242
|
function readVersion4() {
|
|
31018
|
-
const here =
|
|
31243
|
+
const here = dirname17(fileURLToPath5(import.meta.url));
|
|
31019
31244
|
const candidates = [
|
|
31020
31245
|
join44(here, "..", "..", "package.json"),
|
|
31021
31246
|
join44(here, "..", "package.json")
|
|
31022
31247
|
];
|
|
31023
31248
|
for (const p of candidates) {
|
|
31024
|
-
if (
|
|
31249
|
+
if (existsSync49(p)) {
|
|
31025
31250
|
try {
|
|
31026
31251
|
const raw = JSON.parse(readFileSync32(p, "utf8"));
|
|
31027
31252
|
if (raw.version)
|
|
@@ -31115,7 +31340,7 @@ class Repl {
|
|
|
31115
31340
|
this.setupListeners();
|
|
31116
31341
|
}
|
|
31117
31342
|
loadHistory() {
|
|
31118
|
-
if (
|
|
31343
|
+
if (existsSync49(this.historyPath)) {
|
|
31119
31344
|
try {
|
|
31120
31345
|
const raw = readFileSync32(this.historyPath, "utf-8");
|
|
31121
31346
|
this.history = raw.split(`
|
|
@@ -31478,7 +31703,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
31478
31703
|
join44(this.baseDir, ".mma", "AGENTS.md"),
|
|
31479
31704
|
join44(this.configDir, "AGENTS.md")
|
|
31480
31705
|
];
|
|
31481
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
31706
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync49(p));
|
|
31482
31707
|
if (foundAgents.length > 0) {
|
|
31483
31708
|
for (const p of foundAgents) {
|
|
31484
31709
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -31530,18 +31755,29 @@ init_setup();
|
|
|
31530
31755
|
init_config2();
|
|
31531
31756
|
init_i18n();
|
|
31532
31757
|
init_colors();
|
|
31533
|
-
import { existsSync as
|
|
31534
|
-
import { join as join45, dirname as
|
|
31758
|
+
import { existsSync as existsSync50, readFileSync as readFileSync33 } from "fs";
|
|
31759
|
+
import { join as join45, dirname as dirname18 } from "path";
|
|
31535
31760
|
import { homedir as homedir18 } from "os";
|
|
31536
31761
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
31537
31762
|
|
|
31538
31763
|
// src/modules/updater/checker.ts
|
|
31539
31764
|
init_command();
|
|
31540
31765
|
import { platform as platform9 } from "os";
|
|
31766
|
+
function semverGt(a, b) {
|
|
31767
|
+
const pa = a.replace(/^v/, "").split(/[.-]/).map((p) => Number.parseInt(p, 10) || 0);
|
|
31768
|
+
const pb = b.replace(/^v/, "").split(/[.-]/).map((p) => Number.parseInt(p, 10) || 0);
|
|
31769
|
+
for (let i = 0;i < 3; i++) {
|
|
31770
|
+
const na = pa[i] ?? 0;
|
|
31771
|
+
const nb = pb[i] ?? 0;
|
|
31772
|
+
if (na !== nb)
|
|
31773
|
+
return na > nb;
|
|
31774
|
+
}
|
|
31775
|
+
return false;
|
|
31776
|
+
}
|
|
31541
31777
|
var defaultRunner2 = async (command, args, options) => {
|
|
31542
31778
|
const { execFile } = await import("child_process");
|
|
31543
|
-
return new Promise((
|
|
31544
|
-
execFile(command, args, options, (err) =>
|
|
31779
|
+
return new Promise((resolve24) => {
|
|
31780
|
+
execFile(command, args, options, (err) => resolve24({ error: err?.message }));
|
|
31545
31781
|
});
|
|
31546
31782
|
};
|
|
31547
31783
|
|
|
@@ -31574,7 +31810,7 @@ class Updater {
|
|
|
31574
31810
|
if (!latest) {
|
|
31575
31811
|
return { updateAvailable: false, current: this.currentVersion, error: "No latest tag" };
|
|
31576
31812
|
}
|
|
31577
|
-
const updateAvailable = latest
|
|
31813
|
+
const updateAvailable = semverGt(latest, this.currentVersion);
|
|
31578
31814
|
return { updateAvailable, current: this.currentVersion, latest };
|
|
31579
31815
|
} catch (e) {
|
|
31580
31816
|
return { updateAvailable: false, current: this.currentVersion, error: e.message };
|
|
@@ -31616,6 +31852,7 @@ class UpdaterModule {
|
|
|
31616
31852
|
logger;
|
|
31617
31853
|
started = false;
|
|
31618
31854
|
timer = null;
|
|
31855
|
+
idlePromise = null;
|
|
31619
31856
|
installEnabled = true;
|
|
31620
31857
|
constructor(config, currentVersion, packageName, logger, installRunner) {
|
|
31621
31858
|
this.config = config;
|
|
@@ -31639,7 +31876,7 @@ class UpdaterModule {
|
|
|
31639
31876
|
if (this.started || !this.config.enabled)
|
|
31640
31877
|
return;
|
|
31641
31878
|
this.started = true;
|
|
31642
|
-
this.runLoop();
|
|
31879
|
+
this.idlePromise = this.runLoop();
|
|
31643
31880
|
}
|
|
31644
31881
|
stop() {
|
|
31645
31882
|
this.started = false;
|
|
@@ -31648,6 +31885,12 @@ class UpdaterModule {
|
|
|
31648
31885
|
this.timer = null;
|
|
31649
31886
|
}
|
|
31650
31887
|
}
|
|
31888
|
+
async waitForIdle(timeoutMs = 130000) {
|
|
31889
|
+
const idle = this.idlePromise;
|
|
31890
|
+
if (!idle)
|
|
31891
|
+
return;
|
|
31892
|
+
await Promise.race([idle, new Promise((r) => setTimeout(r, timeoutMs))]);
|
|
31893
|
+
}
|
|
31651
31894
|
async runLoop() {
|
|
31652
31895
|
while (this.started) {
|
|
31653
31896
|
await this.checkOnce();
|
|
@@ -31693,13 +31936,13 @@ class UpdaterModule {
|
|
|
31693
31936
|
}
|
|
31694
31937
|
// src/cli/main.ts
|
|
31695
31938
|
function readVersion5() {
|
|
31696
|
-
const here =
|
|
31939
|
+
const here = dirname18(fileURLToPath6(import.meta.url));
|
|
31697
31940
|
const candidates = [
|
|
31698
31941
|
join45(here, "..", "..", "package.json"),
|
|
31699
31942
|
join45(here, "..", "package.json")
|
|
31700
31943
|
];
|
|
31701
31944
|
for (const p of candidates) {
|
|
31702
|
-
if (
|
|
31945
|
+
if (existsSync50(p)) {
|
|
31703
31946
|
try {
|
|
31704
31947
|
const raw = JSON.parse(readFileSync33(p, "utf8"));
|
|
31705
31948
|
if (raw.version)
|
|
@@ -31711,9 +31954,19 @@ function readVersion5() {
|
|
|
31711
31954
|
}
|
|
31712
31955
|
function startAutoUpdate(config) {
|
|
31713
31956
|
try {
|
|
31714
|
-
const module = new UpdaterModule(config.updater, readVersion5(), "micro-models-agent"
|
|
31957
|
+
const module = new UpdaterModule(config.updater, readVersion5(), "micro-models-agent", {
|
|
31958
|
+
info: (m) => process.stderr.write(pc2.dim(m) + `
|
|
31959
|
+
`),
|
|
31960
|
+
warn: (m) => process.stderr.write(pc2.yellow(m) + `
|
|
31961
|
+
`),
|
|
31962
|
+
error: (m) => process.stderr.write(pc2.red(m) + `
|
|
31963
|
+
`)
|
|
31964
|
+
});
|
|
31715
31965
|
module.start();
|
|
31716
|
-
|
|
31966
|
+
return module;
|
|
31967
|
+
} catch {
|
|
31968
|
+
return;
|
|
31969
|
+
}
|
|
31717
31970
|
}
|
|
31718
31971
|
async function main() {
|
|
31719
31972
|
const program2 = createProgram();
|
|
@@ -31731,7 +31984,7 @@ async function main() {
|
|
|
31731
31984
|
if (program2.args.length > 0) {
|
|
31732
31985
|
const prompt = program2.args.join(" ");
|
|
31733
31986
|
const { agent, config } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete);
|
|
31734
|
-
startAutoUpdate(config);
|
|
31987
|
+
const updater = exitOnComplete ? undefined : startAutoUpdate(config);
|
|
31735
31988
|
if (jsonMode) {
|
|
31736
31989
|
const result2 = await agent.run(prompt);
|
|
31737
31990
|
agent.shutdown();
|
|
@@ -31748,6 +32001,7 @@ async function main() {
|
|
|
31748
32001
|
}, null, 2));
|
|
31749
32002
|
process.stdout.write(`
|
|
31750
32003
|
`);
|
|
32004
|
+
await updater?.waitForIdle();
|
|
31751
32005
|
process.exit(result2.success ? 0 : 1);
|
|
31752
32006
|
}
|
|
31753
32007
|
const renderer = new Renderer({
|
|
@@ -31770,10 +32024,11 @@ async function main() {
|
|
|
31770
32024
|
renderer.flush();
|
|
31771
32025
|
const exitCode = printRunResult(result, () => renderer.flush());
|
|
31772
32026
|
agent.shutdown();
|
|
32027
|
+
await updater?.waitForIdle();
|
|
31773
32028
|
process.exit(exitCode);
|
|
31774
32029
|
} else {
|
|
31775
32030
|
const configPath = join45(homedir18(), ".mma", "config.json");
|
|
31776
|
-
if (!
|
|
32031
|
+
if (!existsSync50(configPath)) {
|
|
31777
32032
|
console.log(pc2.yellow(`
|
|
31778
32033
|
` + t("cli.first_run") + `
|
|
31779
32034
|
`));
|