micro-models-agent 0.56.5 → 0.57.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/CHANGELOG.md +481 -463
- package/README.md +358 -358
- package/dist/certification/certifications.json +493 -493
- package/dist/cli/commands.js +447 -0
- package/dist/cli/completer.js +167 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/main.js +153 -0
- package/dist/cli/plugin-commands.js +36 -0
- package/dist/cli/repl-commands.js +761 -0
- package/dist/cli/repl.js +702 -0
- package/dist/cli/run-result.js +33 -0
- package/dist/cli/security-commands.js +164 -0
- package/dist/cli/setup.js +237 -0
- package/dist/config/config.js +276 -0
- package/dist/config/defaults.js +141 -0
- package/dist/config/domains.js +179 -0
- package/dist/config/experts.js +15 -0
- package/dist/config/index.js +4 -0
- package/dist/config/security.js +213 -0
- package/dist/config/types.js +1 -0
- package/dist/core/agent-moe.js +102 -0
- package/dist/core/agent.js +1018 -0
- package/dist/core/bootstrap.js +481 -0
- package/dist/core/crash-handler.js +51 -0
- package/dist/core/environment.js +199 -0
- package/dist/core/index.js +2 -0
- package/dist/core/prompt-builder.js +76 -0
- package/dist/core/session-logger.js +251 -0
- package/dist/core/types.js +1 -0
- package/dist/core/version.js +26 -0
- package/dist/core/workspace.js +76 -0
- package/dist/i18n/en.json +679 -0
- package/dist/i18n/index.js +46 -0
- package/dist/i18n/ru.json +679 -0
- package/dist/index.js +22 -0
- package/dist/llm/image-utils.js +143 -0
- package/dist/llm/index.js +4 -0
- package/dist/llm/model-loader.js +78 -0
- package/dist/llm/openai-compat.js +497 -0
- package/dist/llm/orchestrator.js +200 -0
- package/dist/llm/provider.js +10 -0
- package/dist/llm/response.js +39 -0
- package/dist/llm/token-counter.js +39 -0
- package/dist/llm/types.js +1 -0
- package/dist/logger/app-logger.js +189 -0
- package/dist/logger/file-log.js +151 -0
- package/dist/logger/index.js +1 -0
- package/dist/main.js +457 -324
- package/dist/migration/backup.js +45 -0
- package/dist/migration/detect.js +50 -0
- package/dist/migration/index.js +2 -0
- package/dist/modules/artifacts/store.js +61 -0
- package/dist/modules/browser/actions.js +76 -0
- package/dist/modules/browser/bridge-client.js +199 -0
- package/dist/modules/browser/bridge-path.js +10 -0
- package/dist/modules/browser/bridge-server.mjs +219 -219
- package/dist/modules/browser/cookie-store.js +24 -0
- package/dist/modules/browser/driver.js +136 -0
- package/dist/modules/browser/index.js +7 -0
- package/dist/modules/browser/module.js +29 -0
- package/dist/modules/browser/session.js +342 -0
- package/dist/modules/browser/snapshot.js +148 -0
- package/dist/modules/browser/types.js +12 -0
- package/dist/modules/certification/cli.js +213 -0
- package/dist/modules/certification/fact-checker.js +82 -0
- package/dist/modules/certification/loader.js +106 -0
- package/dist/modules/certification/manifest.js +58 -0
- package/dist/modules/certification/runner.js +245 -0
- package/dist/modules/certification/scenarios.js +407 -0
- package/dist/modules/certification/types.js +1 -0
- package/dist/modules/context/chunk-query.js +100 -0
- package/dist/modules/context/fact-extractor.js +168 -0
- package/dist/modules/context/history.js +15 -0
- package/dist/modules/context/index.js +1 -0
- package/dist/modules/context/manager.js +440 -0
- package/dist/modules/execution/audit-runners.js +206 -0
- package/dist/modules/execution/auditor.js +218 -0
- package/dist/modules/execution/execution-plugin.js +431 -0
- package/dist/modules/execution/index.js +8 -0
- package/dist/modules/execution/module.js +625 -0
- package/dist/modules/execution/moe-executor.js +304 -0
- package/dist/modules/execution/plan-coverage.js +68 -0
- package/dist/modules/execution/plan-persister.js +46 -0
- package/dist/modules/execution/plan-store.js +196 -0
- package/dist/modules/execution/plan-tool.js +677 -0
- package/dist/modules/execution/plan-validator.js +153 -0
- package/dist/modules/execution/planner.js +94 -0
- package/dist/modules/execution/stuck-detector.js +746 -0
- package/dist/modules/execution/tracker.js +69 -0
- package/dist/modules/execution/types.js +1 -0
- package/dist/modules/execution/verifier.js +235 -0
- package/dist/modules/execution/windows-commands.js +41 -0
- package/dist/modules/hallucination/confidence.js +66 -0
- package/dist/modules/hallucination/consistency.js +26 -0
- package/dist/modules/hallucination/detector.js +47 -0
- package/dist/modules/hallucination/factual.js +169 -0
- package/dist/modules/hallucination/index.js +5 -0
- package/dist/modules/hallucination/js-identifiers.js +262 -0
- package/dist/modules/hallucination/llm-judge.js +101 -0
- package/dist/modules/index.js +5 -0
- package/dist/modules/indexer/cache.js +40 -0
- package/dist/modules/indexer/index.js +3 -0
- package/dist/modules/indexer/module.js +246 -0
- package/dist/modules/indexer/project-profile.js +183 -0
- package/dist/modules/indexer/walker.js +101 -0
- package/dist/modules/lsp/check-tool.js +58 -0
- package/dist/modules/lsp/client.js +389 -0
- package/dist/modules/lsp/command.js +60 -0
- package/dist/modules/lsp/config.js +135 -0
- package/dist/modules/lsp/index.js +3 -0
- package/dist/modules/lsp/module.js +260 -0
- package/dist/modules/lsp/probe.js +86 -0
- package/dist/modules/lsp/project-root.js +32 -0
- package/dist/modules/lsp/startup-check.js +144 -0
- package/dist/modules/lsp/types.js +1 -0
- package/dist/modules/mcp/client.js +399 -0
- package/dist/modules/mcp/index.js +3 -0
- package/dist/modules/mcp/module.js +142 -0
- package/dist/modules/mcp/registry.js +15 -0
- package/dist/modules/memory/index.js +1 -0
- package/dist/modules/memory/module.js +96 -0
- package/dist/modules/memory/search.js +42 -0
- package/dist/modules/memory/store.js +69 -0
- package/dist/modules/pipelines/engine.js +60 -0
- package/dist/modules/pipelines/index.js +3 -0
- package/dist/modules/pipelines/parser.js +56 -0
- package/dist/modules/pipelines/template.js +14 -0
- package/dist/modules/plugins/builtin/lint-on-write.js +334 -0
- package/dist/modules/plugins/builtin/notify.js +9 -0
- package/dist/modules/plugins/index.js +1 -0
- package/dist/modules/plugins/loader.js +70 -0
- package/dist/modules/plugins/manager.js +261 -0
- package/dist/modules/plugins/types.js +1 -0
- package/dist/modules/pricing/index.js +61 -0
- package/dist/modules/pricing/prices.js +129 -0
- package/dist/modules/processes/detect.js +34 -0
- package/dist/modules/processes/index.js +2 -0
- package/dist/modules/processes/registry.js +327 -0
- package/dist/modules/processes/runner.js +23 -0
- package/dist/modules/providers/create.js +22 -0
- package/dist/modules/providers/fallback.js +79 -0
- package/dist/modules/providers/health.js +46 -0
- package/dist/modules/providers/index.js +5 -0
- package/dist/modules/providers/manager.js +161 -0
- package/dist/modules/providers/presets.js +128 -0
- package/dist/modules/providers/registry.js +22 -0
- package/dist/modules/providers/types.js +1 -0
- package/dist/modules/registry.js +48 -0
- package/dist/modules/security/audit-log.js +136 -0
- package/dist/modules/security/audit-notifier.js +292 -0
- package/dist/modules/security/command-validator.js +219 -0
- package/dist/modules/security/content-scanner.js +53 -0
- package/dist/modules/security/data-sanitizer.js +89 -0
- package/dist/modules/security/encryption.js +242 -0
- package/dist/modules/security/index.js +14 -0
- package/dist/modules/security/network-validator.js +88 -0
- package/dist/modules/security/path-validator.js +203 -0
- package/dist/modules/security/rate-limiter.js +119 -0
- package/dist/modules/security/security-policies.js +531 -0
- package/dist/modules/security/session-encryption.js +210 -0
- package/dist/modules/security/session-isolation.js +95 -0
- package/dist/modules/session/index.js +3 -0
- package/dist/modules/session/manager.js +172 -0
- package/dist/modules/session/module.js +24 -0
- package/dist/modules/session/store.js +222 -0
- package/dist/modules/session/types.js +1 -0
- package/dist/modules/skills/index.js +2 -0
- package/dist/modules/skills/loader.js +72 -0
- package/dist/modules/skills/matcher.js +27 -0
- package/dist/modules/skills/module.js +129 -0
- package/dist/modules/types.js +1 -0
- package/dist/modules/updater/checker.js +96 -0
- package/dist/modules/updater/index.js +2 -0
- package/dist/modules/updater/module.js +116 -0
- package/dist/modules/user-profile/compressor.js +16 -0
- package/dist/modules/user-profile/index.js +1 -0
- package/dist/modules/user-profile/profile.js +68 -0
- package/dist/skills/builtin/git.md +36 -36
- package/dist/skills/builtin/typescript.md +35 -35
- package/dist/tools/approve.js +33 -0
- package/dist/tools/attach-image.js +101 -0
- package/dist/tools/bash.js +519 -0
- package/dist/tools/browser.js +115 -0
- package/dist/tools/chunk-query.js +100 -0
- package/dist/tools/create-dir.js +56 -0
- package/dist/tools/delete-file.js +63 -0
- package/dist/tools/download-file.js +117 -0
- package/dist/tools/edit-file.js +80 -0
- package/dist/tools/enable-tools.js +59 -0
- package/dist/tools/executor.js +154 -0
- package/dist/tools/file-info.js +47 -0
- package/dist/tools/filter-tools.js +17 -0
- package/dist/tools/glob-tool.js +27 -0
- package/dist/tools/grep-tool.js +125 -0
- package/dist/tools/hidden-tools-block.js +37 -0
- package/dist/tools/index.js +78 -0
- package/dist/tools/list-dir.js +49 -0
- package/dist/tools/load-skill.js +43 -0
- package/dist/tools/mcp-call.js +69 -0
- package/dist/tools/move-file.js +86 -0
- package/dist/tools/path-utils.js +101 -0
- package/dist/tools/pipeline-run.js +145 -0
- package/dist/tools/preview.js +2 -0
- package/dist/tools/process-kill.js +40 -0
- package/dist/tools/process-list.js +37 -0
- package/dist/tools/process-log.js +54 -0
- package/dist/tools/question.js +141 -0
- package/dist/tools/read-file.js +179 -0
- package/dist/tools/recall.js +118 -0
- package/dist/tools/registry.js +47 -0
- package/dist/tools/remember.js +68 -0
- package/dist/tools/scope-check.js +32 -0
- package/dist/tools/search-history.js +85 -0
- package/dist/tools/subagent.js +196 -0
- package/dist/tools/types.js +1 -0
- package/dist/tools/user-input.js +123 -0
- package/dist/tools/web-browse.js +87 -0
- package/dist/tools/web-fetch.js +119 -0
- package/dist/tools/web-search.js +105 -0
- package/dist/tools/write-file.js +82 -0
- package/dist/ui/box.js +77 -0
- package/dist/ui/colors.js +4 -0
- package/dist/ui/diff.js +178 -0
- package/dist/ui/index.js +6 -0
- package/dist/ui/line-editor.js +822 -0
- package/dist/ui/line-math.js +73 -0
- package/dist/ui/md-formatter.js +212 -0
- package/dist/ui/output.js +13 -0
- package/dist/ui/plan-view.js +103 -0
- package/dist/ui/renderer.js +259 -0
- package/dist/ui/spinner.js +70 -0
- package/dist/ui/table.js +144 -0
- package/package.json +51 -51
package/dist/main.js
CHANGED
|
@@ -2329,7 +2329,7 @@ var init_defaults = __esm(() => {
|
|
|
2329
2329
|
maxToolIterations: 1000,
|
|
2330
2330
|
stuckThreshold: 6,
|
|
2331
2331
|
autoPlan: true,
|
|
2332
|
-
showReasoning:
|
|
2332
|
+
showReasoning: true,
|
|
2333
2333
|
logLevel: "info",
|
|
2334
2334
|
locale: "en",
|
|
2335
2335
|
session: {
|
|
@@ -2365,8 +2365,6 @@ var init_defaults = __esm(() => {
|
|
|
2365
2365
|
},
|
|
2366
2366
|
ui: {
|
|
2367
2367
|
spinner: true,
|
|
2368
|
-
toolStyle: "inline",
|
|
2369
|
-
toolComments: true,
|
|
2370
2368
|
showContextStats: false,
|
|
2371
2369
|
showCompaction: true
|
|
2372
2370
|
},
|
|
@@ -2401,8 +2399,8 @@ var init_defaults = __esm(() => {
|
|
|
2401
2399
|
lsp: DEFAULT_LSP_CONFIG,
|
|
2402
2400
|
updater: {
|
|
2403
2401
|
enabled: true,
|
|
2404
|
-
checkOnStart:
|
|
2405
|
-
autoInstall:
|
|
2402
|
+
checkOnStart: false,
|
|
2403
|
+
autoInstall: false,
|
|
2406
2404
|
intervalMs: 0
|
|
2407
2405
|
},
|
|
2408
2406
|
reasoning: {
|
|
@@ -2533,6 +2531,7 @@ The path was joined onto the working directory because it does not exist as give
|
|
|
2533
2531
|
"tool.friendly.web_fetch": "Fetching page",
|
|
2534
2532
|
"tool.friendly.web_browse": "Browsing page",
|
|
2535
2533
|
"tool.friendly.download_file": "Downloading file",
|
|
2534
|
+
"tool.friendly.chunk_query": "Querying chunks",
|
|
2536
2535
|
"tool.web_fetch_result": "Fetched page: {url} — {chars} chars, {lines} lines{truncated}",
|
|
2537
2536
|
"tool.web_browse_result": "Browsed page: {url} — {chars} chars, {lines} lines{truncated}",
|
|
2538
2537
|
"tool.web_search_result": 'Search results for "{query}" — {count} results',
|
|
@@ -3297,6 +3296,7 @@ var init_ru = __esm(() => {
|
|
|
3297
3296
|
"tool.friendly.web_fetch": "Загрузка страницы",
|
|
3298
3297
|
"tool.friendly.web_browse": "Просмотр страницы",
|
|
3299
3298
|
"tool.friendly.download_file": "Скачивание файла",
|
|
3299
|
+
"tool.friendly.chunk_query": "Запрос чанков",
|
|
3300
3300
|
"tool.web_fetch_result": "Загружена страница: {url} — {chars} симв., {lines} строк{truncated}",
|
|
3301
3301
|
"tool.web_browse_result": "Просмотрена страница: {url} — {chars} симв., {lines} строк{truncated}",
|
|
3302
3302
|
"tool.web_search_result": 'Результаты поиска "{query}" — {count} результатов',
|
|
@@ -13453,18 +13453,6 @@ function evaluateReasoningPolicy(input, state) {
|
|
|
13453
13453
|
var DECAY_THRESHOLD = 5;
|
|
13454
13454
|
|
|
13455
13455
|
// src/core/agent.ts
|
|
13456
|
-
function isToolCallJson(text) {
|
|
13457
|
-
const trimmed = text.trim();
|
|
13458
|
-
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
13459
|
-
try {
|
|
13460
|
-
JSON.parse(trimmed);
|
|
13461
|
-
return true;
|
|
13462
|
-
} catch {
|
|
13463
|
-
return false;
|
|
13464
|
-
}
|
|
13465
|
-
}
|
|
13466
|
-
return false;
|
|
13467
|
-
}
|
|
13468
13456
|
function toolOutputCharLimit(remainingBudget, historyBudget, bounded) {
|
|
13469
13457
|
if (bounded)
|
|
13470
13458
|
return Number.MAX_SAFE_INTEGER;
|
|
@@ -13687,6 +13675,10 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13687
13675
|
onPhase,
|
|
13688
13676
|
signal: this.abortController.signal
|
|
13689
13677
|
}) : await this.executeSingleAgentLoop(input, onChunk, onMeta, countTool, onPhase);
|
|
13678
|
+
const provenance = this.callerProvenance();
|
|
13679
|
+
result.provider = provenance.provider;
|
|
13680
|
+
result.model = provenance.model;
|
|
13681
|
+
result.durationMs = Date.now() - startedAt;
|
|
13690
13682
|
emitTurnEnd(result);
|
|
13691
13683
|
return result;
|
|
13692
13684
|
} catch (err) {
|
|
@@ -13730,6 +13722,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13730
13722
|
let emptyResponseExhausted = false;
|
|
13731
13723
|
let auditFailed = false;
|
|
13732
13724
|
let lastAuditSummary = "";
|
|
13725
|
+
let totalLlmDuration = 0;
|
|
13733
13726
|
let suppressRepetitionRetry = false;
|
|
13734
13727
|
let repeatedToolCount = 0;
|
|
13735
13728
|
const MAX_REPEATED_TOOL_CALLS = 2;
|
|
@@ -13868,6 +13861,8 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13868
13861
|
}
|
|
13869
13862
|
textContent += chunk.content;
|
|
13870
13863
|
textChunks.push(chunk.content);
|
|
13864
|
+
const textOut = pluginManager.runOnText({ iteration, logger, contextManager }, chunk.content);
|
|
13865
|
+
onChunk?.(textOut);
|
|
13871
13866
|
}
|
|
13872
13867
|
if (chunk.type === "reasoning" && chunk.content) {
|
|
13873
13868
|
reasoningContent += chunk.content;
|
|
@@ -13930,6 +13925,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13930
13925
|
}
|
|
13931
13926
|
apiCompletionChars += (textContent || reasoningContent).length;
|
|
13932
13927
|
logger.logLLMResponse(config.model, (textContent || reasoningContent).length, Date.now() - llmStart, undefined, "agent");
|
|
13928
|
+
totalLlmDuration += Date.now() - llmStart;
|
|
13933
13929
|
{
|
|
13934
13930
|
const usagePrompt = apiPromptTokens - promptBefore;
|
|
13935
13931
|
const usageCompletion = apiCompletionTokens - completionBefore;
|
|
@@ -13948,14 +13944,6 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
13948
13944
|
if (this.shutdownRequested) {
|
|
13949
13945
|
break;
|
|
13950
13946
|
}
|
|
13951
|
-
const toolComments = this.deps.config.ui?.toolComments ?? true;
|
|
13952
|
-
const showText = textChunks.length > 0 && (!sawToolCall || toolComments && !isToolCallJson(textContent));
|
|
13953
|
-
if (showText) {
|
|
13954
|
-
for (const chunk of textChunks) {
|
|
13955
|
-
const textOut = pluginManager.runOnText({ iteration, logger, contextManager }, chunk);
|
|
13956
|
-
onChunk?.(textOut);
|
|
13957
|
-
}
|
|
13958
|
-
}
|
|
13959
13947
|
let llmResponse = null;
|
|
13960
13948
|
if (sawToolCall) {
|
|
13961
13949
|
llmResponse = { type: "tool_call", calls: toolCalls };
|
|
@@ -14349,7 +14337,8 @@ ${warnLine}
|
|
|
14349
14337
|
totalCost: this.costTracker.total,
|
|
14350
14338
|
costBreakdown: this.costTracker.breakdown(),
|
|
14351
14339
|
compactionCount: contextManager.getCompactionCount(),
|
|
14352
|
-
contextQuality: contextManager.getQuality()
|
|
14340
|
+
contextQuality: contextManager.getQuality(),
|
|
14341
|
+
llmDurationMs: totalLlmDuration
|
|
14353
14342
|
};
|
|
14354
14343
|
}
|
|
14355
14344
|
clearContext() {
|
|
@@ -16957,22 +16946,29 @@ class MCPClient {
|
|
|
16957
16946
|
if (!url)
|
|
16958
16947
|
throw new Error("SSE transport requires a url");
|
|
16959
16948
|
this.abortController = new AbortController;
|
|
16960
|
-
const
|
|
16961
|
-
|
|
16962
|
-
|
|
16963
|
-
|
|
16964
|
-
|
|
16965
|
-
|
|
16966
|
-
|
|
16967
|
-
|
|
16968
|
-
|
|
16969
|
-
|
|
16949
|
+
const timeout = setTimeout(() => this.abortController?.abort(), this.config.timeout || HTTP_TIMEOUT_MS);
|
|
16950
|
+
try {
|
|
16951
|
+
const response = await fetch(url, {
|
|
16952
|
+
method: "GET",
|
|
16953
|
+
headers: {
|
|
16954
|
+
Accept: "text/event-stream",
|
|
16955
|
+
...this.config.headers
|
|
16956
|
+
},
|
|
16957
|
+
signal: this.abortController.signal
|
|
16958
|
+
});
|
|
16959
|
+
clearTimeout(timeout);
|
|
16960
|
+
if (!response.ok) {
|
|
16961
|
+
throw new Error(`SSE connection failed: ${response.status} ${response.statusText}`);
|
|
16962
|
+
}
|
|
16963
|
+
this._connected = true;
|
|
16964
|
+
const reader = response.body.getReader();
|
|
16965
|
+
const decoder = new TextDecoder;
|
|
16966
|
+
let buffer = "";
|
|
16967
|
+
this.readSSE(reader, decoder, buffer);
|
|
16968
|
+
} catch (err) {
|
|
16969
|
+
clearTimeout(timeout);
|
|
16970
|
+
throw err;
|
|
16970
16971
|
}
|
|
16971
|
-
this._connected = true;
|
|
16972
|
-
const reader = response.body.getReader();
|
|
16973
|
-
const decoder = new TextDecoder;
|
|
16974
|
-
let buffer = "";
|
|
16975
|
-
this.readSSE(reader, decoder, buffer);
|
|
16976
16972
|
}
|
|
16977
16973
|
async readSSE(reader, decoder, buffer) {
|
|
16978
16974
|
try {
|
|
@@ -17166,7 +17162,8 @@ class MCPClient {
|
|
|
17166
17162
|
"Content-Type": "application/json",
|
|
17167
17163
|
...this.config.headers
|
|
17168
17164
|
},
|
|
17169
|
-
body: JSON.stringify(request)
|
|
17165
|
+
body: JSON.stringify(request),
|
|
17166
|
+
signal: AbortSignal.timeout(this.config.timeout || HTTP_TIMEOUT_MS)
|
|
17170
17167
|
});
|
|
17171
17168
|
if (!response.ok) {
|
|
17172
17169
|
const text = await response.text().catch(() => "");
|
|
@@ -17252,7 +17249,8 @@ class MCPClient {
|
|
|
17252
17249
|
"Content-Type": "application/json",
|
|
17253
17250
|
...this.config.headers
|
|
17254
17251
|
},
|
|
17255
|
-
body: JSON.stringify(request)
|
|
17252
|
+
body: JSON.stringify(request),
|
|
17253
|
+
signal: AbortSignal.timeout(this.config.timeout || HTTP_TIMEOUT_MS)
|
|
17256
17254
|
});
|
|
17257
17255
|
if (!response.ok) {
|
|
17258
17256
|
const text = await response.text().catch(() => "");
|
|
@@ -17329,6 +17327,7 @@ class MCPClient {
|
|
|
17329
17327
|
});
|
|
17330
17328
|
}
|
|
17331
17329
|
}
|
|
17330
|
+
var HTTP_TIMEOUT_MS = 1e4;
|
|
17332
17331
|
var init_client = () => {};
|
|
17333
17332
|
|
|
17334
17333
|
// src/modules/mcp/registry.ts
|
|
@@ -23982,9 +23981,11 @@ class MCPModule {
|
|
|
23982
23981
|
config;
|
|
23983
23982
|
name = "mcp";
|
|
23984
23983
|
connections = new Map;
|
|
23984
|
+
serverConfigs = new Map;
|
|
23985
23985
|
discovered = [];
|
|
23986
23986
|
initialized = false;
|
|
23987
23987
|
initError = null;
|
|
23988
|
+
failedServers = new Set;
|
|
23988
23989
|
constructor(config) {
|
|
23989
23990
|
this.config = config;
|
|
23990
23991
|
}
|
|
@@ -24011,13 +24012,58 @@ class MCPModule {
|
|
|
24011
24012
|
registry2.register(serverConfig);
|
|
24012
24013
|
}
|
|
24013
24014
|
for (const serverName of registry2.list()) {
|
|
24014
|
-
|
|
24015
|
+
this.serverConfigs.set(serverName, registry2.get(serverName));
|
|
24016
|
+
}
|
|
24017
|
+
this.discoverAllTools();
|
|
24018
|
+
}
|
|
24019
|
+
async discoverAllTools() {
|
|
24020
|
+
for (const [serverName, serverConfig] of this.serverConfigs) {
|
|
24021
|
+
if (this.failedServers.has(serverName))
|
|
24022
|
+
continue;
|
|
24015
24023
|
const client = new MCPClient(serverConfig);
|
|
24016
24024
|
try {
|
|
24017
|
-
await
|
|
24018
|
-
|
|
24019
|
-
|
|
24020
|
-
|
|
24025
|
+
await Promise.race([
|
|
24026
|
+
(async () => {
|
|
24027
|
+
await client.connect();
|
|
24028
|
+
const tools = await client.listTools();
|
|
24029
|
+
this.connections.set(serverName, client);
|
|
24030
|
+
for (const tool of tools) {
|
|
24031
|
+
this.discovered.push({
|
|
24032
|
+
serverName,
|
|
24033
|
+
toolName: tool.name,
|
|
24034
|
+
description: tool.description || `Tool on MCP server "${serverName}"`,
|
|
24035
|
+
inputSchema: tool.inputSchema || {}
|
|
24036
|
+
});
|
|
24037
|
+
}
|
|
24038
|
+
})(),
|
|
24039
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("discovery timeout")), DISCOVERY_TIMEOUT_MS))
|
|
24040
|
+
]);
|
|
24041
|
+
} catch (e) {
|
|
24042
|
+
this.failedServers.add(serverName);
|
|
24043
|
+
this.initError = `MCP server "${serverName}" init failed: ${e.message}`;
|
|
24044
|
+
await client.disconnect().catch((err) => {
|
|
24045
|
+
logger3.warn(`cleanup disconnect for "${serverName}" failed`, { error: String(err) });
|
|
24046
|
+
});
|
|
24047
|
+
}
|
|
24048
|
+
}
|
|
24049
|
+
}
|
|
24050
|
+
async ensureConnected(serverName) {
|
|
24051
|
+
const existing = this.connections.get(serverName);
|
|
24052
|
+
if (existing?.isConnected())
|
|
24053
|
+
return existing;
|
|
24054
|
+
if (this.failedServers.has(serverName))
|
|
24055
|
+
return null;
|
|
24056
|
+
const serverConfig = this.serverConfigs.get(serverName);
|
|
24057
|
+
if (!serverConfig)
|
|
24058
|
+
return null;
|
|
24059
|
+
const client = new MCPClient(serverConfig);
|
|
24060
|
+
try {
|
|
24061
|
+
await client.connect();
|
|
24062
|
+
const tools = await client.listTools();
|
|
24063
|
+
this.connections.set(serverName, client);
|
|
24064
|
+
for (const tool of tools) {
|
|
24065
|
+
const alreadyDiscovered = this.discovered.some((d) => d.serverName === serverName && d.toolName === tool.name);
|
|
24066
|
+
if (!alreadyDiscovered) {
|
|
24021
24067
|
this.discovered.push({
|
|
24022
24068
|
serverName,
|
|
24023
24069
|
toolName: tool.name,
|
|
@@ -24025,16 +24071,18 @@ class MCPModule {
|
|
|
24025
24071
|
inputSchema: tool.inputSchema || {}
|
|
24026
24072
|
});
|
|
24027
24073
|
}
|
|
24028
|
-
} catch (e) {
|
|
24029
|
-
this.initError = `MCP server "${serverName}" init failed: ${e.message}`;
|
|
24030
|
-
await client.disconnect().catch((err) => {
|
|
24031
|
-
logger3.warn(`cleanup disconnect for "${serverName}" failed`, { error: String(err) });
|
|
24032
|
-
});
|
|
24033
24074
|
}
|
|
24075
|
+
return client;
|
|
24076
|
+
} catch (e) {
|
|
24077
|
+
this.failedServers.add(serverName);
|
|
24078
|
+
logger3.warn(`MCP connect failed for "${serverName}": ${e.message}`);
|
|
24079
|
+
await client.disconnect().catch(() => {});
|
|
24080
|
+
return null;
|
|
24034
24081
|
}
|
|
24035
24082
|
}
|
|
24036
24083
|
getSystemPromptBlock() {
|
|
24037
|
-
|
|
24084
|
+
const serverNames = [...this.serverConfigs.keys()];
|
|
24085
|
+
if (serverNames.length === 0)
|
|
24038
24086
|
return null;
|
|
24039
24087
|
const lines = ["---", "MCP servers available:"];
|
|
24040
24088
|
const byServer = new Map;
|
|
@@ -24043,11 +24091,16 @@ class MCPModule {
|
|
|
24043
24091
|
list.push(d);
|
|
24044
24092
|
byServer.set(d.serverName, list);
|
|
24045
24093
|
}
|
|
24046
|
-
for (const
|
|
24047
|
-
lines.push(` [${
|
|
24048
|
-
|
|
24049
|
-
|
|
24050
|
-
|
|
24094
|
+
for (const serverName of serverNames) {
|
|
24095
|
+
lines.push(` [${serverName}]`);
|
|
24096
|
+
const tools = byServer.get(serverName);
|
|
24097
|
+
if (tools && tools.length > 0) {
|
|
24098
|
+
for (const t2 of tools) {
|
|
24099
|
+
const toolRef = sanitizeToolName(serverName, t2.toolName);
|
|
24100
|
+
lines.push(` - ${toolRef}: ${t2.description}`);
|
|
24101
|
+
}
|
|
24102
|
+
} else {
|
|
24103
|
+
lines.push(` (not yet connected — use mcp__${serverName}__connect to discover tools)`);
|
|
24051
24104
|
}
|
|
24052
24105
|
}
|
|
24053
24106
|
lines.push("---");
|
|
@@ -24060,33 +24113,60 @@ class MCPModule {
|
|
|
24060
24113
|
};
|
|
24061
24114
|
}
|
|
24062
24115
|
getToolDefinitions() {
|
|
24063
|
-
|
|
24064
|
-
|
|
24065
|
-
|
|
24066
|
-
|
|
24067
|
-
|
|
24068
|
-
|
|
24069
|
-
|
|
24070
|
-
|
|
24071
|
-
|
|
24072
|
-
|
|
24073
|
-
|
|
24074
|
-
|
|
24116
|
+
const defs = [];
|
|
24117
|
+
for (const d of this.discovered) {
|
|
24118
|
+
defs.push({
|
|
24119
|
+
name: sanitizeToolName(d.serverName, d.toolName),
|
|
24120
|
+
description: `${d.description} [MCP server: ${d.serverName}]`,
|
|
24121
|
+
parameters: convertInputSchema(d.inputSchema),
|
|
24122
|
+
tags: ["code", "research"],
|
|
24123
|
+
handler: async (_ctx, args) => {
|
|
24124
|
+
const client = this.connections.get(d.serverName);
|
|
24125
|
+
if (!client?.isConnected()) {
|
|
24126
|
+
return {
|
|
24127
|
+
success: false,
|
|
24128
|
+
output: `MCP server "${d.serverName}" not connected`
|
|
24129
|
+
};
|
|
24130
|
+
}
|
|
24131
|
+
try {
|
|
24132
|
+
const result = await client.callTool(d.toolName, args);
|
|
24133
|
+
return {
|
|
24134
|
+
success: true,
|
|
24135
|
+
output: typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
24136
|
+
};
|
|
24137
|
+
} catch (e) {
|
|
24138
|
+
return { success: false, output: `MCP call failed: ${e.message}` };
|
|
24139
|
+
}
|
|
24075
24140
|
}
|
|
24076
|
-
|
|
24077
|
-
|
|
24078
|
-
|
|
24141
|
+
});
|
|
24142
|
+
}
|
|
24143
|
+
for (const [serverName] of this.serverConfigs) {
|
|
24144
|
+
if (this.failedServers.has(serverName))
|
|
24145
|
+
continue;
|
|
24146
|
+
const alreadyDiscovered = this.discovered.some((d) => d.serverName === serverName);
|
|
24147
|
+
if (alreadyDiscovered)
|
|
24148
|
+
continue;
|
|
24149
|
+
defs.push({
|
|
24150
|
+
name: sanitizeToolName(serverName, "connect"),
|
|
24151
|
+
description: `Connect to MCP server "${serverName}" and discover its tools`,
|
|
24152
|
+
parameters: { type: "object", properties: {} },
|
|
24153
|
+
tags: ["code", "research"],
|
|
24154
|
+
handler: async (_ctx, _args) => {
|
|
24155
|
+
const client = await this.ensureConnected(serverName);
|
|
24156
|
+
if (!client) {
|
|
24157
|
+
return { success: false, output: `MCP server "${serverName}" connection failed` };
|
|
24079
24158
|
}
|
|
24080
|
-
const
|
|
24159
|
+
const tools = this.discovered.filter((d) => d.serverName === serverName).map((d) => ` - ${sanitizeToolName(serverName, d.toolName)}: ${d.description}`);
|
|
24081
24160
|
return {
|
|
24082
24161
|
success: true,
|
|
24083
|
-
output:
|
|
24162
|
+
output: tools.length > 0 ? `Connected to "${serverName}". Tools:
|
|
24163
|
+
${tools.join(`
|
|
24164
|
+
`)}` : `Connected to "${serverName}" (no tools discovered)`
|
|
24084
24165
|
};
|
|
24085
|
-
} catch (e) {
|
|
24086
|
-
return { success: false, output: `MCP call failed: ${e.message}` };
|
|
24087
24166
|
}
|
|
24088
|
-
}
|
|
24089
|
-
}
|
|
24167
|
+
});
|
|
24168
|
+
}
|
|
24169
|
+
return defs;
|
|
24090
24170
|
}
|
|
24091
24171
|
getPlugin() {
|
|
24092
24172
|
return {
|
|
@@ -24104,7 +24184,7 @@ class MCPModule {
|
|
|
24104
24184
|
};
|
|
24105
24185
|
}
|
|
24106
24186
|
}
|
|
24107
|
-
var logger3;
|
|
24187
|
+
var logger3, DISCOVERY_TIMEOUT_MS = 5000;
|
|
24108
24188
|
var init_module7 = __esm(() => {
|
|
24109
24189
|
init_client();
|
|
24110
24190
|
init_app_logger();
|
|
@@ -24584,6 +24664,12 @@ __export(exports_probe, {
|
|
|
24584
24664
|
getCachedProbeResult: () => getCachedProbeResult,
|
|
24585
24665
|
cacheKey: () => cacheKey
|
|
24586
24666
|
});
|
|
24667
|
+
import { existsSync as existsSync50, readFileSync as readFileSync31, writeFileSync as writeFileSync19, mkdirSync as mkdirSync20 } from "fs";
|
|
24668
|
+
import { join as join42, dirname as dirname18 } from "path";
|
|
24669
|
+
import { homedir as homedir14 } from "os";
|
|
24670
|
+
function cachePath() {
|
|
24671
|
+
return join42(homedir14(), ".mma", "reasoning-cache.json");
|
|
24672
|
+
}
|
|
24587
24673
|
async function probeReasoningSupport(provider, strategy, signal) {
|
|
24588
24674
|
if (strategy === "none")
|
|
24589
24675
|
return false;
|
|
@@ -24606,20 +24692,58 @@ function cacheKey(baseUrl, model) {
|
|
|
24606
24692
|
return `${baseUrl}|${model}`;
|
|
24607
24693
|
}
|
|
24608
24694
|
function getCachedProbeResult(key) {
|
|
24609
|
-
|
|
24695
|
+
const mem = memCache.get(key);
|
|
24696
|
+
if (mem && Date.now() - mem.ts < CACHE_TTL_MS) {
|
|
24697
|
+
return mem.result;
|
|
24698
|
+
}
|
|
24699
|
+
const disk = readDiskCache();
|
|
24700
|
+
const entry = disk[key];
|
|
24701
|
+
if (entry) {
|
|
24702
|
+
const age = Date.now() - new Date(entry.ts).getTime();
|
|
24703
|
+
if (age < CACHE_TTL_MS) {
|
|
24704
|
+
memCache.set(key, { result: entry.result, ts: Date.now() });
|
|
24705
|
+
return entry.result;
|
|
24706
|
+
}
|
|
24707
|
+
}
|
|
24708
|
+
return;
|
|
24610
24709
|
}
|
|
24611
24710
|
function setCachedProbeResult(key, result) {
|
|
24612
|
-
|
|
24711
|
+
const now = new Date().toISOString();
|
|
24712
|
+
memCache.set(key, { result, ts: Date.now() });
|
|
24713
|
+
const disk = readDiskCache();
|
|
24714
|
+
disk[key] = { result, ts: now };
|
|
24715
|
+
writeDiskCache(disk);
|
|
24613
24716
|
}
|
|
24614
24717
|
function resetProbeCache() {
|
|
24615
|
-
|
|
24718
|
+
memCache.clear();
|
|
24719
|
+
const path = cachePath();
|
|
24720
|
+
if (existsSync50(path)) {
|
|
24721
|
+
writeFileSync19(path, "{}", "utf-8");
|
|
24722
|
+
}
|
|
24723
|
+
}
|
|
24724
|
+
function readDiskCache() {
|
|
24725
|
+
try {
|
|
24726
|
+
const path = cachePath();
|
|
24727
|
+
if (existsSync50(path)) {
|
|
24728
|
+
return JSON.parse(readFileSync31(path, "utf-8"));
|
|
24729
|
+
}
|
|
24730
|
+
} catch {}
|
|
24731
|
+
return {};
|
|
24616
24732
|
}
|
|
24617
|
-
|
|
24733
|
+
function writeDiskCache(data) {
|
|
24734
|
+
try {
|
|
24735
|
+
const path = cachePath();
|
|
24736
|
+
mkdirSync20(dirname18(path), { recursive: true });
|
|
24737
|
+
writeFileSync19(path, JSON.stringify(data, null, 2), "utf-8");
|
|
24738
|
+
} catch {}
|
|
24739
|
+
}
|
|
24740
|
+
var PROBE_MESSAGES, CACHE_TTL_MS, memCache;
|
|
24618
24741
|
var init_probe = __esm(() => {
|
|
24619
24742
|
PROBE_MESSAGES = [
|
|
24620
24743
|
{ role: "user", content: "Reply with exactly: ok" }
|
|
24621
24744
|
];
|
|
24622
|
-
|
|
24745
|
+
CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
24746
|
+
memCache = new Map;
|
|
24623
24747
|
});
|
|
24624
24748
|
|
|
24625
24749
|
// src/tools/set-thinking.ts
|
|
@@ -24701,9 +24825,9 @@ __export(exports_bootstrap, {
|
|
|
24701
24825
|
buildSystemInfo: () => buildSystemInfo,
|
|
24702
24826
|
bootstrap: () => bootstrap
|
|
24703
24827
|
});
|
|
24704
|
-
import { homedir as
|
|
24705
|
-
import { join as
|
|
24706
|
-
import { existsSync as
|
|
24828
|
+
import { homedir as homedir15 } from "os";
|
|
24829
|
+
import { join as join43, resolve as resolve22 } from "path";
|
|
24830
|
+
import { existsSync as existsSync51, readFileSync as readFileSync32, writeFileSync as writeFileSync20 } from "fs";
|
|
24707
24831
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
24708
24832
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
24709
24833
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -24756,8 +24880,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
24756
24880
|
`);
|
|
24757
24881
|
}
|
|
24758
24882
|
async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reasoningLevel) {
|
|
24759
|
-
const dir = configDir || process.env.MMA_CONFIG_DIR ||
|
|
24760
|
-
const projectConfigPath = projectDir ?
|
|
24883
|
+
const dir = configDir || process.env.MMA_CONFIG_DIR || join43(homedir15(), ".mma");
|
|
24884
|
+
const projectConfigPath = projectDir ? join43(projectDir, ".mmrc") : join43(process.cwd(), ".mmrc");
|
|
24761
24885
|
const { config, legacyDetected } = loadConfig({ configDir: dir, projectConfigPath });
|
|
24762
24886
|
setLocale(config.locale);
|
|
24763
24887
|
if (reasoningLevel && reasoningLevel !== "auto") {
|
|
@@ -24773,7 +24897,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24773
24897
|
}
|
|
24774
24898
|
} catch {}
|
|
24775
24899
|
const logger4 = new Logger(config.logLevel);
|
|
24776
|
-
logger4.setLogDir(
|
|
24900
|
+
logger4.setLogDir(join43(dir, "logs"));
|
|
24777
24901
|
logger4.debug("MMA bootstrap", {
|
|
24778
24902
|
version: config.version,
|
|
24779
24903
|
model: config.model
|
|
@@ -24802,7 +24926,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24802
24926
|
logger4.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
|
|
24803
24927
|
}
|
|
24804
24928
|
}
|
|
24805
|
-
const profile = new UserProfile(
|
|
24929
|
+
const profile = new UserProfile(join43(dir));
|
|
24806
24930
|
profile.load() || profile.collect();
|
|
24807
24931
|
profile.save();
|
|
24808
24932
|
const providerManager = new ProviderManager(config.provider, {
|
|
@@ -24852,7 +24976,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24852
24976
|
for (const warning of envReport.warnings) {
|
|
24853
24977
|
logger4.warn(warning);
|
|
24854
24978
|
}
|
|
24855
|
-
const projectMapCacheDir =
|
|
24979
|
+
const projectMapCacheDir = join43(baseDir, ".mma");
|
|
24856
24980
|
const indexerModule = new IndexerModule({
|
|
24857
24981
|
baseDir,
|
|
24858
24982
|
cacheDir: projectMapCacheDir
|
|
@@ -24863,9 +24987,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24863
24987
|
logger4.warn(`Project indexing failed: ${err.message}`);
|
|
24864
24988
|
}
|
|
24865
24989
|
const skillsLoader = new SkillsLoader;
|
|
24866
|
-
const builtinDir =
|
|
24867
|
-
const globalDir =
|
|
24868
|
-
const projectSkillsDir =
|
|
24990
|
+
const builtinDir = join43(import.meta.dirname, "skills", "builtin");
|
|
24991
|
+
const globalDir = join43(homedir15(), ".agents", "skills");
|
|
24992
|
+
const projectSkillsDir = join43(baseDir, ".mma", "skills");
|
|
24869
24993
|
const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
|
|
24870
24994
|
const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
|
|
24871
24995
|
const skillsModule = new SkillsModule(availableSkills, skillsBudget);
|
|
@@ -24881,11 +25005,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24881
25005
|
essential: true,
|
|
24882
25006
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
24883
25007
|
};
|
|
24884
|
-
const agentsMdGlobal =
|
|
24885
|
-
if (!
|
|
24886
|
-
|
|
25008
|
+
const agentsMdGlobal = join43(dir, "AGENTS.md");
|
|
25009
|
+
if (!existsSync51(agentsMdGlobal)) {
|
|
25010
|
+
writeFileSync20(agentsMdGlobal, "", "utf-8");
|
|
24887
25011
|
}
|
|
24888
|
-
const sessionDir =
|
|
25012
|
+
const sessionDir = join43(dir, "sessions");
|
|
24889
25013
|
const sessionStore = new SessionStore(sessionDir);
|
|
24890
25014
|
sessionStore.init();
|
|
24891
25015
|
const sessionManager = new SessionManager(sessionStore, {
|
|
@@ -24959,7 +25083,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
24959
25083
|
const mcpModule = new MCPModule(config);
|
|
24960
25084
|
await mcpModule.initialize();
|
|
24961
25085
|
moduleRegistry.register(mcpModule);
|
|
24962
|
-
const memoryStore = new MemoryStore(
|
|
25086
|
+
const memoryStore = new MemoryStore(join43(dir, "memory"));
|
|
24963
25087
|
const memoryModule = new MemoryModule(memoryStore);
|
|
24964
25088
|
moduleRegistry.register(memoryModule);
|
|
24965
25089
|
if (config.browser.enabled) {
|
|
@@ -25013,8 +25137,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
25013
25137
|
pluginManager.register(plugin);
|
|
25014
25138
|
pluginManager.register(plugin2);
|
|
25015
25139
|
const pluginLoader = new PluginLoader;
|
|
25016
|
-
const globalPluginsDir =
|
|
25017
|
-
const projectPluginsDir =
|
|
25140
|
+
const globalPluginsDir = join43(homedir15(), ".mma", "plugins");
|
|
25141
|
+
const projectPluginsDir = join43(baseDir, ".mma", "plugins");
|
|
25018
25142
|
const mmaVersion = readMmaVersion();
|
|
25019
25143
|
pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger4, {
|
|
25020
25144
|
source: "global",
|
|
@@ -25040,13 +25164,13 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
25040
25164
|
const skipAgentsMd = noAgentsMd === true;
|
|
25041
25165
|
if (!skipAgentsMd) {
|
|
25042
25166
|
const agentsMdCandidates = [
|
|
25043
|
-
|
|
25044
|
-
|
|
25045
|
-
|
|
25167
|
+
join43(baseDir, "AGENTS.md"),
|
|
25168
|
+
join43(baseDir, ".mma", "AGENTS.md"),
|
|
25169
|
+
join43(dir, "AGENTS.md")
|
|
25046
25170
|
];
|
|
25047
25171
|
for (const p of agentsMdCandidates) {
|
|
25048
|
-
if (
|
|
25049
|
-
const content =
|
|
25172
|
+
if (existsSync51(p)) {
|
|
25173
|
+
const content = readFileSync32(p, "utf-8").trim();
|
|
25050
25174
|
if (content) {
|
|
25051
25175
|
agentsMdBlocks.push({
|
|
25052
25176
|
content,
|
|
@@ -33432,8 +33556,8 @@ var init_scenarios = __esm(() => {
|
|
|
33432
33556
|
});
|
|
33433
33557
|
|
|
33434
33558
|
// src/modules/certification/loader.ts
|
|
33435
|
-
import { existsSync as
|
|
33436
|
-
import { join as
|
|
33559
|
+
import { existsSync as existsSync53, readdirSync as readdirSync17, readFileSync as readFileSync34 } from "fs";
|
|
33560
|
+
import { join as join46 } from "path";
|
|
33437
33561
|
function validateScenario(s) {
|
|
33438
33562
|
const errors2 = [];
|
|
33439
33563
|
const isSkip = s.mode === "skip";
|
|
@@ -33485,12 +33609,12 @@ function loadScenarios(userDir) {
|
|
|
33485
33609
|
else
|
|
33486
33610
|
scenarios.push(s);
|
|
33487
33611
|
}
|
|
33488
|
-
if (userDir &&
|
|
33612
|
+
if (userDir && existsSync53(userDir)) {
|
|
33489
33613
|
for (const file of readdirSync17(userDir)) {
|
|
33490
33614
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
33491
33615
|
continue;
|
|
33492
33616
|
try {
|
|
33493
|
-
const raw =
|
|
33617
|
+
const raw = readFileSync34(join46(userDir, file), "utf-8");
|
|
33494
33618
|
const data = $parse(raw);
|
|
33495
33619
|
const parsed = normalizeScenario(data, file);
|
|
33496
33620
|
const errs = validateScenario(parsed);
|
|
@@ -33553,8 +33677,8 @@ var init_loader3 = __esm(() => {
|
|
|
33553
33677
|
});
|
|
33554
33678
|
|
|
33555
33679
|
// src/modules/certification/fact-checker.ts
|
|
33556
|
-
import { existsSync as
|
|
33557
|
-
import { join as
|
|
33680
|
+
import { existsSync as existsSync54, readFileSync as readFileSync35, statSync as statSync9 } from "fs";
|
|
33681
|
+
import { join as join47 } from "path";
|
|
33558
33682
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
33559
33683
|
const failures = [];
|
|
33560
33684
|
for (const check of checks) {
|
|
@@ -33571,16 +33695,16 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33571
33695
|
case "outputContains":
|
|
33572
33696
|
return output.includes(check.text);
|
|
33573
33697
|
case "fileExists":
|
|
33574
|
-
return isFile(
|
|
33698
|
+
return isFile(join47(sandboxDir, check.path));
|
|
33575
33699
|
case "fileNotExists":
|
|
33576
|
-
return !
|
|
33700
|
+
return !existsSync54(join47(sandboxDir, check.path));
|
|
33577
33701
|
case "dirExists":
|
|
33578
|
-
return isDir(
|
|
33702
|
+
return isDir(join47(sandboxDir, check.path));
|
|
33579
33703
|
case "fileContent": {
|
|
33580
|
-
const abs =
|
|
33704
|
+
const abs = join47(sandboxDir, check.path);
|
|
33581
33705
|
if (!isFile(abs))
|
|
33582
33706
|
return false;
|
|
33583
|
-
const content =
|
|
33707
|
+
const content = readFileSync35(abs, "utf-8");
|
|
33584
33708
|
if (check.contains !== undefined)
|
|
33585
33709
|
return content.includes(check.contains);
|
|
33586
33710
|
if (check.equals !== undefined)
|
|
@@ -33588,10 +33712,10 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33588
33712
|
return false;
|
|
33589
33713
|
}
|
|
33590
33714
|
case "fileRegex": {
|
|
33591
|
-
const abs =
|
|
33715
|
+
const abs = join47(sandboxDir, check.path);
|
|
33592
33716
|
if (!isFile(abs))
|
|
33593
33717
|
return false;
|
|
33594
|
-
return new RegExp(check.pattern).test(
|
|
33718
|
+
return new RegExp(check.pattern).test(readFileSync35(abs, "utf-8"));
|
|
33595
33719
|
}
|
|
33596
33720
|
default:
|
|
33597
33721
|
return false;
|
|
@@ -33599,14 +33723,14 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
33599
33723
|
}
|
|
33600
33724
|
function isFile(p) {
|
|
33601
33725
|
try {
|
|
33602
|
-
return
|
|
33726
|
+
return existsSync54(p) && statSync9(p).isFile();
|
|
33603
33727
|
} catch {
|
|
33604
33728
|
return false;
|
|
33605
33729
|
}
|
|
33606
33730
|
}
|
|
33607
33731
|
function isDir(p) {
|
|
33608
33732
|
try {
|
|
33609
|
-
return
|
|
33733
|
+
return existsSync54(p) && statSync9(p).isDirectory();
|
|
33610
33734
|
} catch {
|
|
33611
33735
|
return false;
|
|
33612
33736
|
}
|
|
@@ -33637,8 +33761,8 @@ var init_fact_checker = () => {};
|
|
|
33637
33761
|
|
|
33638
33762
|
// src/modules/certification/runner.ts
|
|
33639
33763
|
import { spawn as spawn10 } from "child_process";
|
|
33640
|
-
import { existsSync as
|
|
33641
|
-
import { join as
|
|
33764
|
+
import { existsSync as existsSync55, mkdirSync as mkdirSync21, rmSync as rmSync4, cpSync as cpSync2, writeFileSync as writeFileSync21, readdirSync as readdirSync18, readFileSync as readFileSync36 } from "fs";
|
|
33765
|
+
import { join as join48, resolve as resolve23, dirname as dirname21, relative as relative7 } from "path";
|
|
33642
33766
|
async function runScenario(scenario, opts) {
|
|
33643
33767
|
if (scenario.mode === "skip") {
|
|
33644
33768
|
return {
|
|
@@ -33658,7 +33782,7 @@ async function runScenario(scenario, opts) {
|
|
|
33658
33782
|
let firstError;
|
|
33659
33783
|
let lastFailedSandbox;
|
|
33660
33784
|
for (let i = 1;i <= reps; i++) {
|
|
33661
|
-
const sandbox =
|
|
33785
|
+
const sandbox = join48(opts.sandboxBase, `run-${scenario.id}-${i}`);
|
|
33662
33786
|
let failures = [];
|
|
33663
33787
|
let exitCode = -1;
|
|
33664
33788
|
let output = "";
|
|
@@ -33682,9 +33806,9 @@ async function runScenario(scenario, opts) {
|
|
|
33682
33806
|
env3.MMA_PROVIDER_APIKEY = opts.providerKey;
|
|
33683
33807
|
if (scenario.config && opts.baseConfig) {
|
|
33684
33808
|
const merged = deepMergeAny(opts.baseConfig, scenario.config);
|
|
33685
|
-
const certConfigDir =
|
|
33686
|
-
|
|
33687
|
-
|
|
33809
|
+
const certConfigDir = join48(sandbox, ".mma");
|
|
33810
|
+
mkdirSync21(certConfigDir, { recursive: true });
|
|
33811
|
+
writeFileSync21(join48(certConfigDir, "config.json"), JSON.stringify(merged, null, 2), "utf-8");
|
|
33688
33812
|
env3.MMA_CONFIG_DIR = certConfigDir;
|
|
33689
33813
|
}
|
|
33690
33814
|
const res = await runner(env3, opts.mmaRoot, args, timeoutMs);
|
|
@@ -33729,14 +33853,14 @@ ${res.stderr}`;
|
|
|
33729
33853
|
}
|
|
33730
33854
|
function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
33731
33855
|
rmSync4(sandbox, { recursive: true, force: true });
|
|
33732
|
-
|
|
33856
|
+
mkdirSync21(sandbox, { recursive: true });
|
|
33733
33857
|
for (const f of scenario.fixtures ?? []) {
|
|
33734
|
-
const src =
|
|
33735
|
-
if (!
|
|
33858
|
+
const src = join48(mmaRoot, f.source);
|
|
33859
|
+
if (!existsSync55(src)) {
|
|
33736
33860
|
throw new Error(`fixture missing: ${f.source}`);
|
|
33737
33861
|
}
|
|
33738
|
-
const dest =
|
|
33739
|
-
|
|
33862
|
+
const dest = join48(sandbox, f.dest);
|
|
33863
|
+
mkdirSync21(dirname21(dest), { recursive: true });
|
|
33740
33864
|
cpSync2(src, dest);
|
|
33741
33865
|
}
|
|
33742
33866
|
}
|
|
@@ -33748,10 +33872,10 @@ function collectDiagnostics(sandbox) {
|
|
|
33748
33872
|
} else {
|
|
33749
33873
|
lines.push(" Files created: (none)");
|
|
33750
33874
|
}
|
|
33751
|
-
const planPath =
|
|
33752
|
-
if (
|
|
33875
|
+
const planPath = join48(sandbox, ".mma", "plans", "active.json");
|
|
33876
|
+
if (existsSync55(planPath)) {
|
|
33753
33877
|
try {
|
|
33754
|
-
const plan = JSON.parse(
|
|
33878
|
+
const plan = JSON.parse(readFileSync36(planPath, "utf-8"));
|
|
33755
33879
|
const steps = plan.steps ?? [];
|
|
33756
33880
|
const done = steps.filter((s) => s.status === "done").length;
|
|
33757
33881
|
const pending = steps.filter((s) => s.status === "pending" || s.status === "in_progress");
|
|
@@ -33770,7 +33894,7 @@ function listFiles(dir, root) {
|
|
|
33770
33894
|
for (const entry of readdirSync18(dir, { withFileTypes: true })) {
|
|
33771
33895
|
if (entry.name === ".mma")
|
|
33772
33896
|
continue;
|
|
33773
|
-
const abs =
|
|
33897
|
+
const abs = join48(dir, entry.name);
|
|
33774
33898
|
const rel = toForwardSlash(relative7(root, abs));
|
|
33775
33899
|
if (entry.isDirectory()) {
|
|
33776
33900
|
result.push(...listFiles(abs, root));
|
|
@@ -33782,15 +33906,15 @@ function listFiles(dir, root) {
|
|
|
33782
33906
|
return result;
|
|
33783
33907
|
}
|
|
33784
33908
|
function resolveMmaEntry(mmaRoot) {
|
|
33785
|
-
const dev =
|
|
33786
|
-
if (
|
|
33909
|
+
const dev = join48(mmaRoot, "src", "cli", "main.ts");
|
|
33910
|
+
if (existsSync55(dev))
|
|
33787
33911
|
return dev;
|
|
33788
|
-
return
|
|
33912
|
+
return join48(mmaRoot, "dist", "main.js");
|
|
33789
33913
|
}
|
|
33790
33914
|
function findMmaRoot(fromDir) {
|
|
33791
33915
|
const candidates = [resolve23(fromDir, "..", "..", ".."), resolve23(fromDir, "..")];
|
|
33792
33916
|
for (const c of candidates) {
|
|
33793
|
-
if (
|
|
33917
|
+
if (existsSync55(join48(c, "package.json")))
|
|
33794
33918
|
return c;
|
|
33795
33919
|
}
|
|
33796
33920
|
return process.cwd();
|
|
@@ -33857,16 +33981,16 @@ __export(exports_cli, {
|
|
|
33857
33981
|
certStatus: () => certStatus,
|
|
33858
33982
|
certList: () => certList
|
|
33859
33983
|
});
|
|
33860
|
-
import { rmSync as rmSync5, writeFileSync as
|
|
33861
|
-
import { join as
|
|
33984
|
+
import { rmSync as rmSync5, writeFileSync as writeFileSync22 } from "fs";
|
|
33985
|
+
import { join as join49, dirname as dirname22 } from "path";
|
|
33862
33986
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
33863
|
-
import { existsSync as
|
|
33987
|
+
import { existsSync as existsSync56, readFileSync as readFileSync37 } from "fs";
|
|
33864
33988
|
function readVersion() {
|
|
33865
|
-
const candidates = [
|
|
33989
|
+
const candidates = [join49(MMA_ROOT, "package.json")];
|
|
33866
33990
|
for (const p of candidates) {
|
|
33867
|
-
if (
|
|
33991
|
+
if (existsSync56(p)) {
|
|
33868
33992
|
try {
|
|
33869
|
-
const raw = JSON.parse(
|
|
33993
|
+
const raw = JSON.parse(readFileSync37(p, "utf-8"));
|
|
33870
33994
|
if (raw.version)
|
|
33871
33995
|
return raw.version;
|
|
33872
33996
|
} catch {}
|
|
@@ -33879,7 +34003,7 @@ function parseTags(s) {
|
|
|
33879
34003
|
}
|
|
33880
34004
|
async function certify(opts) {
|
|
33881
34005
|
const providerUrl = opts.providerUrl || opts.config.provider.baseUrl;
|
|
33882
|
-
const { scenarios, errors: errors2 } = loadScenarios(
|
|
34006
|
+
const { scenarios, errors: errors2 } = loadScenarios(join49(opts.projectDir, ".mma", "certification", "scenarios"));
|
|
33883
34007
|
for (const e of errors2)
|
|
33884
34008
|
console.error(pc2.yellow(` ${e}`));
|
|
33885
34009
|
let selected = filterByTags(scenarios, opts.tags);
|
|
@@ -33910,7 +34034,7 @@ async function certify(opts) {
|
|
|
33910
34034
|
return;
|
|
33911
34035
|
}
|
|
33912
34036
|
console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
|
|
33913
|
-
const sandboxBase =
|
|
34037
|
+
const sandboxBase = join49(process.cwd(), ".mma", "certification");
|
|
33914
34038
|
const results = [];
|
|
33915
34039
|
const total = selected.length;
|
|
33916
34040
|
let idx = 0;
|
|
@@ -34043,10 +34167,10 @@ function printResults(results) {
|
|
|
34043
34167
|
}
|
|
34044
34168
|
}
|
|
34045
34169
|
function writeReport(entry, projectDir) {
|
|
34046
|
-
const reportDir =
|
|
34170
|
+
const reportDir = join49(projectDir, "certification");
|
|
34047
34171
|
const ts = entry.certifiedAt.replace(/[:.]/g, "-").slice(0, 19);
|
|
34048
34172
|
const filename = `report-${entry.model.replace(/[/\\:]/g, "_")}-${ts}.json`;
|
|
34049
|
-
const reportPath =
|
|
34173
|
+
const reportPath = join49(reportDir, filename);
|
|
34050
34174
|
const report = {
|
|
34051
34175
|
model: entry.model,
|
|
34052
34176
|
providerUrl: entry.providerUrl,
|
|
@@ -34065,7 +34189,7 @@ function writeReport(entry, projectDir) {
|
|
|
34065
34189
|
}))
|
|
34066
34190
|
};
|
|
34067
34191
|
try {
|
|
34068
|
-
|
|
34192
|
+
writeFileSync22(reportPath, JSON.stringify(report, null, 2), "utf-8");
|
|
34069
34193
|
console.log(pc2.dim(`
|
|
34070
34194
|
Report: ${reportPath}`));
|
|
34071
34195
|
} catch (e) {
|
|
@@ -34079,7 +34203,7 @@ var init_cli = __esm(() => {
|
|
|
34079
34203
|
init_loader3();
|
|
34080
34204
|
init_runner2();
|
|
34081
34205
|
init_manifest();
|
|
34082
|
-
HERE =
|
|
34206
|
+
HERE = dirname22(fileURLToPath5(import.meta.url));
|
|
34083
34207
|
MMA_ROOT = findMmaRoot(HERE);
|
|
34084
34208
|
});
|
|
34085
34209
|
|
|
@@ -34089,8 +34213,8 @@ __export(exports_repl_commands, {
|
|
|
34089
34213
|
registerAllCommands: () => registerAllCommands,
|
|
34090
34214
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
34091
34215
|
});
|
|
34092
|
-
import { join as
|
|
34093
|
-
import { existsSync as
|
|
34216
|
+
import { join as join51, dirname as dirname24 } from "path";
|
|
34217
|
+
import { existsSync as existsSync58 } from "fs";
|
|
34094
34218
|
function registerAllCommands(ctx) {
|
|
34095
34219
|
registerBuiltinCommands(ctx);
|
|
34096
34220
|
registerMmaCommands(ctx);
|
|
@@ -34147,7 +34271,7 @@ function registerMmaCommands(ctx) {
|
|
|
34147
34271
|
}
|
|
34148
34272
|
try {
|
|
34149
34273
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
34150
|
-
const { existsSync:
|
|
34274
|
+
const { existsSync: existsSync59 } = await import("fs");
|
|
34151
34275
|
const { resolve: resolve24 } = await import("path");
|
|
34152
34276
|
let dataUrl;
|
|
34153
34277
|
let label;
|
|
@@ -34167,7 +34291,7 @@ function registerMmaCommands(ctx) {
|
|
|
34167
34291
|
label = source;
|
|
34168
34292
|
} else {
|
|
34169
34293
|
const absPath = resolve24(process.cwd(), source);
|
|
34170
|
-
if (!
|
|
34294
|
+
if (!existsSync59(absPath)) {
|
|
34171
34295
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
34172
34296
|
return;
|
|
34173
34297
|
}
|
|
@@ -34270,7 +34394,7 @@ function registerMmaCommands(ctx) {
|
|
|
34270
34394
|
console.log(pc2.yellow(t("repl.wizard_running")));
|
|
34271
34395
|
await ctx.withExclusiveInput(async () => {
|
|
34272
34396
|
const answers = await runSetup(ctx.rl);
|
|
34273
|
-
const configPath =
|
|
34397
|
+
const configPath = join51(ctx.configDir, "config.json");
|
|
34274
34398
|
ctx.config.provider.type = answers.provider;
|
|
34275
34399
|
ctx.config.provider.baseUrl = answers.apiBase;
|
|
34276
34400
|
ctx.config.provider.apiKey = answers.apiKey;
|
|
@@ -34278,7 +34402,7 @@ function registerMmaCommands(ctx) {
|
|
|
34278
34402
|
ctx.config.contextWindow = answers.contextWindow;
|
|
34279
34403
|
ctx.config.maxToolIterations = answers.maxToolIterations;
|
|
34280
34404
|
ctx.config.locale = answers.locale;
|
|
34281
|
-
saveConfig(ctx.config, configPath,
|
|
34405
|
+
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
34282
34406
|
await ctx.agent.reconfigure(ctx.config);
|
|
34283
34407
|
console.log(pc2.green(t("cli.config_saved")));
|
|
34284
34408
|
});
|
|
@@ -34392,8 +34516,8 @@ function registerMmaCommands(ctx) {
|
|
|
34392
34516
|
return;
|
|
34393
34517
|
}
|
|
34394
34518
|
ctx.config.model = name;
|
|
34395
|
-
const configPath =
|
|
34396
|
-
saveConfig(ctx.config, configPath,
|
|
34519
|
+
const configPath = join51(ctx.configDir, "config.json");
|
|
34520
|
+
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
34397
34521
|
await ctx.agent.reconfigure(ctx.config);
|
|
34398
34522
|
console.log(pc2.green(t("repl.model_set", { name })));
|
|
34399
34523
|
return;
|
|
@@ -34417,8 +34541,8 @@ function registerMmaCommands(ctx) {
|
|
|
34417
34541
|
return;
|
|
34418
34542
|
}
|
|
34419
34543
|
ctx.config.contextWindow = size;
|
|
34420
|
-
const configPath =
|
|
34421
|
-
saveConfig(ctx.config, configPath,
|
|
34544
|
+
const configPath = join51(ctx.configDir, "config.json");
|
|
34545
|
+
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
34422
34546
|
await ctx.agent.reconfigure(ctx.config);
|
|
34423
34547
|
console.log(pc2.green(t("cli.context_set", { size })));
|
|
34424
34548
|
}
|
|
@@ -34432,10 +34556,10 @@ function registerMmaCommands(ctx) {
|
|
|
34432
34556
|
if (ctx.sessionManager && ctx.config.session.autoSave) {}
|
|
34433
34557
|
ctx.agent.shutdown();
|
|
34434
34558
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
34435
|
-
const { join:
|
|
34559
|
+
const { join: join52 } = await import("path");
|
|
34436
34560
|
const configDir = ctx.configDir;
|
|
34437
34561
|
const baseDir = ctx.baseDir;
|
|
34438
|
-
const projectConfigPath =
|
|
34562
|
+
const projectConfigPath = join52(baseDir, ".mmrc");
|
|
34439
34563
|
const { config: freshConfig } = loadConfig2({ configDir, projectConfigPath });
|
|
34440
34564
|
Object.assign(ctx.config, freshConfig);
|
|
34441
34565
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -34789,21 +34913,21 @@ async function runConfigMigrate(ctx) {
|
|
|
34789
34913
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
34790
34914
|
const { loadConfig: loadCfg } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
34791
34915
|
const configDir = ctx.configDir;
|
|
34792
|
-
const configPath =
|
|
34916
|
+
const configPath = join51(configDir, "config.json");
|
|
34793
34917
|
if (hasDomainFiles3(configDir)) {
|
|
34794
34918
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
34795
34919
|
return;
|
|
34796
34920
|
}
|
|
34797
|
-
if (!
|
|
34921
|
+
if (!existsSync58(configPath)) {
|
|
34798
34922
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
34799
34923
|
return;
|
|
34800
34924
|
}
|
|
34801
34925
|
console.log(t("config.migrate_start"));
|
|
34802
|
-
const { config } = loadCfg({ configDir, projectConfigPath:
|
|
34926
|
+
const { config } = loadCfg({ configDir, projectConfigPath: join51(configDir, ".mmrc") });
|
|
34803
34927
|
saveConfig(config, configPath, configDir);
|
|
34804
34928
|
const { renameSync: renameSync4, readdirSync: readdirSync19 } = await import("fs");
|
|
34805
34929
|
renameSync4(configPath, configPath + ".bak");
|
|
34806
|
-
const domainFiles = readdirSync19(
|
|
34930
|
+
const domainFiles = readdirSync19(join51(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
34807
34931
|
console.log(pc2.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
34808
34932
|
}
|
|
34809
34933
|
var version2, COMMAND_GROUPS;
|
|
@@ -34863,15 +34987,15 @@ init_config2();
|
|
|
34863
34987
|
init_setup();
|
|
34864
34988
|
init_i18n();
|
|
34865
34989
|
init_colors();
|
|
34866
|
-
import { join as
|
|
34867
|
-
import { homedir as
|
|
34868
|
-
import { existsSync as
|
|
34990
|
+
import { join as join50, dirname as dirname23 } from "path";
|
|
34991
|
+
import { homedir as homedir17 } from "os";
|
|
34992
|
+
import { existsSync as existsSync57 } from "fs";
|
|
34869
34993
|
|
|
34870
34994
|
// src/cli/security-commands.ts
|
|
34871
34995
|
init_bootstrap();
|
|
34872
34996
|
init_config2();
|
|
34873
|
-
import { join as
|
|
34874
|
-
import { homedir as
|
|
34997
|
+
import { join as join44, dirname as dirname19 } from "path";
|
|
34998
|
+
import { homedir as homedir16 } from "os";
|
|
34875
34999
|
|
|
34876
35000
|
// src/modules/security/security-policies.ts
|
|
34877
35001
|
init_security();
|
|
@@ -35396,7 +35520,7 @@ function createSecurityCommand(program2) {
|
|
|
35396
35520
|
}
|
|
35397
35521
|
});
|
|
35398
35522
|
securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
|
|
35399
|
-
const configPath =
|
|
35523
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35400
35524
|
const { config: appConfig } = await bootstrap();
|
|
35401
35525
|
const validPresets = ["strict", "balanced", "permissive"];
|
|
35402
35526
|
if (!validPresets.includes(preset)) {
|
|
@@ -35406,40 +35530,40 @@ function createSecurityCommand(program2) {
|
|
|
35406
35530
|
const policy = getSecurityPolicy(preset);
|
|
35407
35531
|
const newSecurityConfig = applySecurityPolicy(preset);
|
|
35408
35532
|
appConfig.security = newSecurityConfig;
|
|
35409
|
-
saveConfig(appConfig, configPath,
|
|
35533
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35410
35534
|
console.log(t("cli.security.policy_applied", { name: policy.name }));
|
|
35411
35535
|
console.log(t("cli.security.policy_description", { description: policy.description }));
|
|
35412
35536
|
});
|
|
35413
35537
|
securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
|
|
35414
|
-
const configPath =
|
|
35538
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35415
35539
|
const { config: appConfig } = await bootstrap();
|
|
35416
35540
|
const security = appConfig.security = appConfig.security || {};
|
|
35417
35541
|
toggleSessionEncryption(security, true);
|
|
35418
|
-
saveConfig(appConfig, configPath,
|
|
35542
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35419
35543
|
console.log(t("cli.security.encryption_enabled"));
|
|
35420
35544
|
});
|
|
35421
35545
|
securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
|
|
35422
|
-
const configPath =
|
|
35546
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35423
35547
|
const { config: appConfig } = await bootstrap();
|
|
35424
35548
|
const security = appConfig.security = appConfig.security || {};
|
|
35425
35549
|
toggleSessionEncryption(security, false);
|
|
35426
|
-
saveConfig(appConfig, configPath,
|
|
35550
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35427
35551
|
console.log(t("cli.security.encryption_disabled"));
|
|
35428
35552
|
});
|
|
35429
35553
|
securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
|
|
35430
|
-
const configPath =
|
|
35554
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35431
35555
|
const { config: appConfig } = await bootstrap();
|
|
35432
35556
|
const security = appConfig.security = appConfig.security || {};
|
|
35433
35557
|
toggleAuditNotifier(security, true);
|
|
35434
|
-
saveConfig(appConfig, configPath,
|
|
35558
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35435
35559
|
console.log(t("cli.security.audit_enabled"));
|
|
35436
35560
|
});
|
|
35437
35561
|
securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
|
|
35438
|
-
const configPath =
|
|
35562
|
+
const configPath = join44(homedir16(), ".mma", "config.json");
|
|
35439
35563
|
const { config: appConfig } = await bootstrap();
|
|
35440
35564
|
const security = appConfig.security = appConfig.security || {};
|
|
35441
35565
|
toggleAuditNotifier(security, false);
|
|
35442
|
-
saveConfig(appConfig, configPath,
|
|
35566
|
+
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
35443
35567
|
console.log(t("cli.security.audit_disabled"));
|
|
35444
35568
|
});
|
|
35445
35569
|
securityCmd.command("audit-stats").description(t("cli.security.audit_stats")).action(async () => {
|
|
@@ -35498,27 +35622,27 @@ init_presets();
|
|
|
35498
35622
|
init_version();
|
|
35499
35623
|
|
|
35500
35624
|
// src/modules/updater/changelog-reader.ts
|
|
35501
|
-
import { readFileSync as
|
|
35502
|
-
import { dirname as
|
|
35625
|
+
import { readFileSync as readFileSync33, existsSync as existsSync52 } from "fs";
|
|
35626
|
+
import { dirname as dirname20, join as join45 } from "path";
|
|
35503
35627
|
function readChangelog(packageName) {
|
|
35504
35628
|
try {
|
|
35505
|
-
let dir =
|
|
35629
|
+
let dir = dirname20(import.meta.url);
|
|
35506
35630
|
if (dir.startsWith("file://")) {
|
|
35507
35631
|
dir = decodeURIComponent(dir.slice(7));
|
|
35508
35632
|
}
|
|
35509
35633
|
for (let i = 0;i < 10; i++) {
|
|
35510
|
-
const pkgPath =
|
|
35511
|
-
if (
|
|
35512
|
-
const pkg = JSON.parse(
|
|
35634
|
+
const pkgPath = join45(dir, "package.json");
|
|
35635
|
+
if (existsSync52(pkgPath)) {
|
|
35636
|
+
const pkg = JSON.parse(readFileSync33(pkgPath, "utf-8"));
|
|
35513
35637
|
if (pkg.name === packageName) {
|
|
35514
|
-
const changelogPath =
|
|
35515
|
-
if (
|
|
35516
|
-
return
|
|
35638
|
+
const changelogPath = join45(dir, "CHANGELOG.md");
|
|
35639
|
+
if (existsSync52(changelogPath)) {
|
|
35640
|
+
return readFileSync33(changelogPath, "utf-8");
|
|
35517
35641
|
}
|
|
35518
35642
|
return null;
|
|
35519
35643
|
}
|
|
35520
35644
|
}
|
|
35521
|
-
dir =
|
|
35645
|
+
dir = dirname20(dir);
|
|
35522
35646
|
}
|
|
35523
35647
|
return null;
|
|
35524
35648
|
} catch {
|
|
@@ -35581,7 +35705,7 @@ function createProgram() {
|
|
|
35581
35705
|
const program2 = new Command().name("mma").description(t("cli.description")).version(version).option("--no-agents-md", t("cli.no_agents_md")).option("-d, --dir <path>", t("cli.dir")).option("-e, --exit-on-complete", t("cli.exit_on_complete")).option("-j, --json", t("cli.json")).option("--reasoning <level>", t("cli.reasoning_level"), "auto");
|
|
35582
35706
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
35583
35707
|
const answers = await runSetup();
|
|
35584
|
-
const configPath =
|
|
35708
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35585
35709
|
const { config } = await bootstrap();
|
|
35586
35710
|
config.provider.type = answers.provider;
|
|
35587
35711
|
config.provider.baseUrl = answers.apiBase;
|
|
@@ -35621,12 +35745,12 @@ function createProgram() {
|
|
|
35621
35745
|
config.security.paths.denied = [];
|
|
35622
35746
|
}
|
|
35623
35747
|
}
|
|
35624
|
-
saveConfig(config, configPath,
|
|
35748
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35625
35749
|
console.log(t("cli.config_saved"));
|
|
35626
35750
|
});
|
|
35627
35751
|
const configCmd = program2.command("config").description(t("cli.manage_config"));
|
|
35628
35752
|
configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
|
|
35629
|
-
const configPath =
|
|
35753
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35630
35754
|
const { config } = await bootstrap();
|
|
35631
35755
|
const keys = key.split(".");
|
|
35632
35756
|
let obj = config;
|
|
@@ -35646,7 +35770,7 @@ function createProgram() {
|
|
|
35646
35770
|
obj[lastKey] = parseFloat(value);
|
|
35647
35771
|
else
|
|
35648
35772
|
obj[lastKey] = value;
|
|
35649
|
-
saveConfig(config, configPath,
|
|
35773
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35650
35774
|
console.log(t("cli.set_done", { key, value }));
|
|
35651
35775
|
});
|
|
35652
35776
|
configCmd.command("show").description(t("cli.show_config")).action(async () => {
|
|
@@ -35656,24 +35780,24 @@ function createProgram() {
|
|
|
35656
35780
|
configCmd.command("migrate").description(t("cli.migrate_config")).action(async () => {
|
|
35657
35781
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
35658
35782
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
35659
|
-
const configDir =
|
|
35660
|
-
const configPath =
|
|
35783
|
+
const configDir = join50(homedir17(), ".mma");
|
|
35784
|
+
const configPath = join50(configDir, "config.json");
|
|
35661
35785
|
if (hasDomainFiles3(configDir)) {
|
|
35662
35786
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
35663
35787
|
return;
|
|
35664
35788
|
}
|
|
35665
|
-
if (!
|
|
35789
|
+
if (!existsSync57(configPath)) {
|
|
35666
35790
|
console.log(pc2.yellow(t("config.migrate_no_legacy")));
|
|
35667
35791
|
return;
|
|
35668
35792
|
}
|
|
35669
35793
|
console.log(t("config.migrate_start"));
|
|
35670
|
-
const { config } = loadConfig2({ configDir, projectConfigPath:
|
|
35794
|
+
const { config } = loadConfig2({ configDir, projectConfigPath: join50(configDir, ".mmrc") });
|
|
35671
35795
|
saveConfig(config, configPath, configDir);
|
|
35672
35796
|
const bakPath = configPath + ".bak";
|
|
35673
35797
|
const { renameSync: renameSync4 } = await import("fs");
|
|
35674
35798
|
renameSync4(configPath, bakPath);
|
|
35675
35799
|
const { readdirSync: readdirSync19 } = await import("fs");
|
|
35676
|
-
const domainFiles = readdirSync19(
|
|
35800
|
+
const domainFiles = readdirSync19(join50(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
35677
35801
|
console.log(pc2.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
35678
35802
|
});
|
|
35679
35803
|
const model = program2.command("model").description(t("cli.manage_models"));
|
|
@@ -35713,10 +35837,10 @@ function createProgram() {
|
|
|
35713
35837
|
console.log(t("cli.model_hint"));
|
|
35714
35838
|
});
|
|
35715
35839
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
35716
|
-
const configPath =
|
|
35840
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35717
35841
|
const { config } = await bootstrap();
|
|
35718
35842
|
config.model = name;
|
|
35719
|
-
saveConfig(config, configPath,
|
|
35843
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35720
35844
|
console.log(t("cli.model_set", { name }));
|
|
35721
35845
|
});
|
|
35722
35846
|
model.command("certify").argument("<name>", "Model name").option("--provider-url <url>", t("cli.cert_provider_url")).option("--provider-key <key>", t("cli.cert_provider_key")).option("--context-window <n>", t("cli.cert_context_window")).option("--tags <tags>", t("cli.cert_tags"), "core").option("--scenarios <ids>", t("cli.cert_scenarios")).option("--timeout <ms>", t("cli.cert_timeout")).option("--reps <n>", t("cli.cert_reps")).option("--force", t("cli.cert_force")).option("--clean", t("cli.cert_clean")).description(t("cli.certify")).action(async (name, cmdOpts) => {
|
|
@@ -35752,7 +35876,7 @@ function createProgram() {
|
|
|
35752
35876
|
await uncertify2(name, config, process.cwd());
|
|
35753
35877
|
});
|
|
35754
35878
|
program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
|
|
35755
|
-
const configPath =
|
|
35879
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35756
35880
|
const { config } = await bootstrap();
|
|
35757
35881
|
const contextWindow = parseInt(size, 10);
|
|
35758
35882
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
@@ -35760,7 +35884,7 @@ function createProgram() {
|
|
|
35760
35884
|
return;
|
|
35761
35885
|
}
|
|
35762
35886
|
config.contextWindow = contextWindow;
|
|
35763
|
-
saveConfig(config, configPath,
|
|
35887
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35764
35888
|
console.log(t("cli.context_set", { size: contextWindow }));
|
|
35765
35889
|
});
|
|
35766
35890
|
const provider = program2.command("provider").description(t("cli.manage_providers"));
|
|
@@ -35798,7 +35922,7 @@ function createProgram() {
|
|
|
35798
35922
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
35799
35923
|
});
|
|
35800
35924
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
35801
|
-
const configPath =
|
|
35925
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35802
35926
|
const { config, agent } = await bootstrap();
|
|
35803
35927
|
if (config.provider.entries && config.provider.entries.length > 0) {
|
|
35804
35928
|
try {
|
|
@@ -35814,14 +35938,14 @@ function createProgram() {
|
|
|
35814
35938
|
if (baseUrl) {
|
|
35815
35939
|
config.provider.baseUrl = baseUrl;
|
|
35816
35940
|
}
|
|
35817
|
-
saveConfig(config, configPath,
|
|
35941
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35818
35942
|
console.log(t("cli.provider_set", { name }));
|
|
35819
35943
|
if (baseUrl) {
|
|
35820
35944
|
console.log(t("cli.provider_base_hint", { baseUrl }));
|
|
35821
35945
|
}
|
|
35822
35946
|
});
|
|
35823
35947
|
provider.command("add").argument("<name>", "Provider type or label").option("--url <url>", "Base URL").option("--key <key>", "API key").option("--priority <n>", "Fallback priority (lower = tried first)").option("--context-window <n>", "Context window override for this entry").option("--rpm <n>", "Max requests per minute for this entry").option("--parallel <n>", "Max parallel tasks for this entry").description(t("cli.add_provider")).action(async (name, opts) => {
|
|
35824
|
-
const configPath =
|
|
35948
|
+
const configPath = join50(homedir17(), ".mma", "config.json");
|
|
35825
35949
|
const { config } = await bootstrap();
|
|
35826
35950
|
const entries = Array.isArray(config.provider.entries) ? config.provider.entries : [];
|
|
35827
35951
|
if (entries.length === 0) {
|
|
@@ -35853,7 +35977,7 @@ function createProgram() {
|
|
|
35853
35977
|
});
|
|
35854
35978
|
config.provider.entries = entries;
|
|
35855
35979
|
config.provider.active = config.provider.active || config.provider.type;
|
|
35856
|
-
saveConfig(config, configPath,
|
|
35980
|
+
saveConfig(config, configPath, dirname23(configPath));
|
|
35857
35981
|
console.log(pc2.green(t("cli.provider_added", { name })));
|
|
35858
35982
|
console.log(t("cli.provider_switch_hint"));
|
|
35859
35983
|
});
|
|
@@ -36795,9 +36919,9 @@ class LineEditor {
|
|
|
36795
36919
|
}
|
|
36796
36920
|
|
|
36797
36921
|
// src/cli/repl.ts
|
|
36798
|
-
import { existsSync as
|
|
36799
|
-
import { join as
|
|
36800
|
-
import { homedir as
|
|
36922
|
+
import { existsSync as existsSync59, readFileSync as readFileSync40, writeFileSync as writeFileSync23 } from "fs";
|
|
36923
|
+
import { join as join52 } from "path";
|
|
36924
|
+
import { homedir as homedir18 } from "os";
|
|
36801
36925
|
|
|
36802
36926
|
// src/cli/completer.ts
|
|
36803
36927
|
class SlashCommandProvider {
|
|
@@ -36983,9 +37107,12 @@ class FormattingStream {
|
|
|
36983
37107
|
codeLines = [];
|
|
36984
37108
|
tableBuffer = [];
|
|
36985
37109
|
onWrite;
|
|
37110
|
+
onRawWrite;
|
|
36986
37111
|
width;
|
|
36987
|
-
|
|
37112
|
+
partialWritten = 0;
|
|
37113
|
+
constructor(onWrite, width, onRawWrite) {
|
|
36988
37114
|
this.onWrite = onWrite;
|
|
37115
|
+
this.onRawWrite = onRawWrite ?? onWrite;
|
|
36989
37116
|
this.width = width ?? getTerminalWidth();
|
|
36990
37117
|
}
|
|
36991
37118
|
write(chunk) {
|
|
@@ -36995,8 +37122,20 @@ class FormattingStream {
|
|
|
36995
37122
|
`)) !== -1) {
|
|
36996
37123
|
const line = this.buffer.slice(0, idx);
|
|
36997
37124
|
this.buffer = this.buffer.slice(idx + 1);
|
|
37125
|
+
this.emitPartialRewind();
|
|
36998
37126
|
this.processLine(line);
|
|
36999
37127
|
}
|
|
37128
|
+
if (this.buffer.length > 0 && !this.inCodeBlock) {
|
|
37129
|
+
this.onRawWrite(this.buffer);
|
|
37130
|
+
this.partialWritten = this.buffer.length;
|
|
37131
|
+
this.buffer = "";
|
|
37132
|
+
}
|
|
37133
|
+
}
|
|
37134
|
+
emitPartialRewind() {
|
|
37135
|
+
if (this.partialWritten > 0) {
|
|
37136
|
+
this.onRawWrite(`\x1B[${this.partialWritten}D`);
|
|
37137
|
+
this.partialWritten = 0;
|
|
37138
|
+
}
|
|
37000
37139
|
}
|
|
37001
37140
|
flush() {
|
|
37002
37141
|
if (this.tableBuffer.length > 0) {
|
|
@@ -37133,7 +37272,6 @@ function formatWarning(text) {
|
|
|
37133
37272
|
|
|
37134
37273
|
// src/ui/renderer.ts
|
|
37135
37274
|
init_spinner();
|
|
37136
|
-
init_box();
|
|
37137
37275
|
init_table();
|
|
37138
37276
|
init_i18n();
|
|
37139
37277
|
init_prices();
|
|
@@ -37160,6 +37298,7 @@ function toDisplayPath(baseDir, p) {
|
|
|
37160
37298
|
return rel.split(sep2).join("/");
|
|
37161
37299
|
}
|
|
37162
37300
|
var GUTTER = " ";
|
|
37301
|
+
var MAX_OUTPUT_LINES = 50;
|
|
37163
37302
|
var BUSY_TOOLS = new Set(["lsp_check"]);
|
|
37164
37303
|
function toolMarker(tool) {
|
|
37165
37304
|
switch (tool) {
|
|
@@ -37211,15 +37350,19 @@ class Renderer {
|
|
|
37211
37350
|
out;
|
|
37212
37351
|
err;
|
|
37213
37352
|
width;
|
|
37214
|
-
toolStyle;
|
|
37215
37353
|
baseDir;
|
|
37216
37354
|
card = null;
|
|
37355
|
+
thoughtStarted = false;
|
|
37356
|
+
thoughtStartMs = 0;
|
|
37357
|
+
thoughtHeaderPrinted = false;
|
|
37358
|
+
textStarted = false;
|
|
37359
|
+
outputLineCount = 0;
|
|
37360
|
+
outputSuppressed = false;
|
|
37217
37361
|
constructor(opts = {}) {
|
|
37218
37362
|
this.rich = opts.rich ?? isRichTerminal();
|
|
37219
37363
|
this.out = opts.out ?? process.stdout;
|
|
37220
37364
|
this.err = opts.err ?? process.stderr;
|
|
37221
37365
|
this.width = opts.width ?? getTerminalWidth();
|
|
37222
|
-
this.toolStyle = opts.toolStyle ?? "inline";
|
|
37223
37366
|
this.baseDir = opts.baseDir;
|
|
37224
37367
|
this.spinner = new Spinner({
|
|
37225
37368
|
enabled: this.rich && (opts.spinner ?? true),
|
|
@@ -37227,21 +37370,32 @@ class Renderer {
|
|
|
37227
37370
|
width: this.width
|
|
37228
37371
|
});
|
|
37229
37372
|
this.fmt = new FormattingStream((line) => this.out.write(`${line}
|
|
37230
|
-
`), this.width);
|
|
37373
|
+
`), this.width, (text) => this.out.write(text));
|
|
37374
|
+
}
|
|
37375
|
+
showLoader() {
|
|
37376
|
+
this.spinner.start("thinking");
|
|
37231
37377
|
}
|
|
37232
37378
|
text(chunk) {
|
|
37233
37379
|
this.endCard();
|
|
37234
37380
|
this.spinner.stop();
|
|
37381
|
+
if (!this.textStarted) {
|
|
37382
|
+
this.textStarted = true;
|
|
37383
|
+
this.out.write(`
|
|
37384
|
+
${pc2.dim("-")} `);
|
|
37385
|
+
}
|
|
37235
37386
|
this.fmt.write(chunk);
|
|
37236
37387
|
}
|
|
37237
37388
|
meta(chunk) {
|
|
37238
37389
|
this.spinner.stop();
|
|
37239
|
-
if (this.
|
|
37240
|
-
if (this.
|
|
37241
|
-
this.
|
|
37242
|
-
|
|
37243
|
-
this.
|
|
37244
|
-
}
|
|
37390
|
+
if (this.thoughtStarted) {
|
|
37391
|
+
if (!this.thoughtHeaderPrinted) {
|
|
37392
|
+
this.out.write(`
|
|
37393
|
+
${pc2.dim("→")} Thought: `);
|
|
37394
|
+
this.thoughtHeaderPrinted = true;
|
|
37395
|
+
}
|
|
37396
|
+
this.out.write(pc2.dim(chunk));
|
|
37397
|
+
} else if (this.card) {
|
|
37398
|
+
this.writeInlineBody(chunk);
|
|
37245
37399
|
} else {
|
|
37246
37400
|
this.out.write(chunk);
|
|
37247
37401
|
}
|
|
@@ -37251,44 +37405,55 @@ class Renderer {
|
|
|
37251
37405
|
`)) {
|
|
37252
37406
|
if (line.trim() === "")
|
|
37253
37407
|
continue;
|
|
37408
|
+
this.outputLineCount++;
|
|
37409
|
+
if (this.outputLineCount > MAX_OUTPUT_LINES) {
|
|
37410
|
+
this.outputSuppressed = true;
|
|
37411
|
+
continue;
|
|
37412
|
+
}
|
|
37254
37413
|
this.out.write(`${GUTTER}${line}
|
|
37255
37414
|
`);
|
|
37256
37415
|
}
|
|
37257
37416
|
}
|
|
37258
37417
|
reasoning(chunk) {
|
|
37259
37418
|
this.spinner.stop();
|
|
37419
|
+
if (this.thoughtStarted && !this.thoughtHeaderPrinted) {
|
|
37420
|
+
this.out.write(`
|
|
37421
|
+
${pc2.dim("→")} Thought: `);
|
|
37422
|
+
this.thoughtHeaderPrinted = true;
|
|
37423
|
+
}
|
|
37260
37424
|
this.out.write(pc2.dim(chunk));
|
|
37261
37425
|
}
|
|
37262
37426
|
thinkingStart() {
|
|
37263
|
-
this.
|
|
37427
|
+
this.thoughtStarted = true;
|
|
37428
|
+
this.thoughtStartMs = Date.now();
|
|
37429
|
+
this.thoughtHeaderPrinted = false;
|
|
37264
37430
|
}
|
|
37265
37431
|
thinkingEnd() {
|
|
37266
37432
|
this.spinner.stop();
|
|
37433
|
+
if (this.thoughtStarted && this.thoughtHeaderPrinted) {
|
|
37434
|
+
const duration = Date.now() - this.thoughtStartMs;
|
|
37435
|
+
this.out.write(pc2.dim(` ${duration}ms
|
|
37436
|
+
`));
|
|
37437
|
+
}
|
|
37438
|
+
this.thoughtStarted = false;
|
|
37439
|
+
this.thoughtHeaderPrinted = false;
|
|
37267
37440
|
}
|
|
37268
37441
|
toolStart(tool, args, stepContext, icon) {
|
|
37269
37442
|
this.endCard();
|
|
37270
37443
|
this.spinner.stop();
|
|
37444
|
+
this.outputLineCount = 0;
|
|
37445
|
+
this.outputSuppressed = false;
|
|
37271
37446
|
const displayArgs = PATH_TOOLS.has(tool) && typeof args.path === "string" ? { ...args, path: toDisplayPath(this.baseDir, args.path) } : args;
|
|
37272
37447
|
const summary = summarizeArgs2(displayArgs);
|
|
37273
|
-
const step = stepContext ? ` ${pc2.cyan(`← ${stepContext}`)}` : "";
|
|
37274
37448
|
const marker = icon || toolMarker(tool);
|
|
37275
|
-
|
|
37449
|
+
this.card = { tool, args, start: Date.now() };
|
|
37450
|
+
if (stepContext) {
|
|
37276
37451
|
this.out.write(`
|
|
37277
|
-
${pc2.dim(
|
|
37452
|
+
${pc2.dim("↓")} ${pc2.cyan(stepContext)}
|
|
37278
37453
|
`);
|
|
37279
|
-
return;
|
|
37280
37454
|
}
|
|
37281
|
-
this.
|
|
37282
|
-
if (this.toolStyle === "inline") {
|
|
37283
|
-
this.out.write(`
|
|
37284
|
-
${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}
|
|
37455
|
+
this.out.write(`${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
37285
37456
|
`);
|
|
37286
|
-
if (BUSY_TOOLS.has(tool)) {
|
|
37287
|
-
this.spinner.start(t("ui.tool_running", { tool: friendlyTool(tool) }));
|
|
37288
|
-
}
|
|
37289
|
-
return;
|
|
37290
|
-
}
|
|
37291
|
-
this.spinner.start(`${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}${step}`);
|
|
37292
37457
|
}
|
|
37293
37458
|
planBlock(lines) {
|
|
37294
37459
|
this.endCard();
|
|
@@ -37298,30 +37463,12 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
37298
37463
|
`);
|
|
37299
37464
|
}
|
|
37300
37465
|
}
|
|
37301
|
-
toolEnd(_tool, duration, error, ctxDelta, costUsd
|
|
37466
|
+
toolEnd(_tool, duration, error, ctxDelta, costUsd) {
|
|
37302
37467
|
this.spinner.stop();
|
|
37303
|
-
const prov = provider && model ? `${pc2.dim(`${provider}·${model}`)}` : undefined;
|
|
37304
|
-
if (!this.rich) {
|
|
37305
|
-
const parts = [];
|
|
37306
|
-
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
37307
|
-
const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
|
|
37308
|
-
parts.push(`${pc2.dim("ctx")} ${deltaStr}`);
|
|
37309
|
-
}
|
|
37310
|
-
if (costUsd !== undefined && costUsd > 0) {
|
|
37311
|
-
parts.push(`${pc2.dim("cost")} ${pc2.yellow(formatUsd(costUsd))}`);
|
|
37312
|
-
}
|
|
37313
|
-
if (prov)
|
|
37314
|
-
parts.push(prov);
|
|
37315
|
-
if (parts.length > 0)
|
|
37316
|
-
this.out.write(`${parts.join(" ")}
|
|
37317
|
-
`);
|
|
37318
|
-
return;
|
|
37319
|
-
}
|
|
37320
37468
|
if (!this.card)
|
|
37321
37469
|
return;
|
|
37322
|
-
const { tool, args, body } = this.card;
|
|
37323
37470
|
const marker = error ? pc2.red("✗") : pc2.green("✓");
|
|
37324
|
-
let footer = `${marker} ${pc2.dim(`${duration}ms`)}`;
|
|
37471
|
+
let footer = `${GUTTER}${marker} ${pc2.dim(`${duration}ms`)}`;
|
|
37325
37472
|
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
37326
37473
|
const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
|
|
37327
37474
|
footer += ` ${pc2.dim("ctx")} ${deltaStr}`;
|
|
@@ -37329,32 +37476,10 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
37329
37476
|
if (costUsd !== undefined && costUsd > 0) {
|
|
37330
37477
|
footer += ` ${pc2.dim("cost")} ${pc2.yellow(formatUsd(costUsd))}`;
|
|
37331
37478
|
}
|
|
37332
|
-
|
|
37333
|
-
footer += ` ${pc2.dim("via")} ${prov}`;
|
|
37334
|
-
}
|
|
37335
|
-
if (this.toolStyle === "inline") {
|
|
37336
|
-
this.out.write(`${GUTTER}${footer}
|
|
37479
|
+
this.out.write(`${footer}
|
|
37337
37480
|
`);
|
|
37338
|
-
|
|
37339
|
-
`)
|
|
37340
|
-
this.card = null;
|
|
37341
|
-
return;
|
|
37342
|
-
}
|
|
37343
|
-
const lines = [];
|
|
37344
|
-
const summary = summarizeArgs2(args);
|
|
37345
|
-
if (summary)
|
|
37346
|
-
lines.push(pc2.dim(summary));
|
|
37347
|
-
for (const chunk of body) {
|
|
37348
|
-
for (const line of chunk.split(`
|
|
37349
|
-
`)) {
|
|
37350
|
-
if (line.trim() !== "")
|
|
37351
|
-
lines.push(line);
|
|
37352
|
-
}
|
|
37353
|
-
}
|
|
37354
|
-
lines.push(footer);
|
|
37355
|
-
const title = `${marker} ${friendlyTool(tool)}`;
|
|
37356
|
-
for (const line of box(lines, { title, width: this.width })) {
|
|
37357
|
-
this.out.write(`${line}
|
|
37481
|
+
if (this.outputSuppressed) {
|
|
37482
|
+
this.out.write(`${GUTTER}${pc2.dim(`... (${this.outputLineCount - MAX_OUTPUT_LINES} more lines)`)}
|
|
37358
37483
|
`);
|
|
37359
37484
|
}
|
|
37360
37485
|
this.card = null;
|
|
@@ -37374,6 +37499,12 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
37374
37499
|
this.endCard();
|
|
37375
37500
|
this.spinner.stop();
|
|
37376
37501
|
this.fmt.flush();
|
|
37502
|
+
this.textStarted = false;
|
|
37503
|
+
}
|
|
37504
|
+
footer(model, provider, durationMs) {
|
|
37505
|
+
this.out.write(`
|
|
37506
|
+
${pc2.dim("▣")} ${model} · ${provider} · ${pc2.dim(`${durationMs}ms`)}
|
|
37507
|
+
`);
|
|
37377
37508
|
}
|
|
37378
37509
|
endCard() {
|
|
37379
37510
|
if (!this.card)
|
|
@@ -37527,20 +37658,16 @@ function stepContextForTool(plan, tool, args) {
|
|
|
37527
37658
|
const argStr = JSON.stringify(args);
|
|
37528
37659
|
const callPaths = extractFileLikeTokens(stripUrls(argStr)).map((p) => p.toLowerCase());
|
|
37529
37660
|
if (callPaths.length > 0) {
|
|
37530
|
-
for (const
|
|
37531
|
-
if (
|
|
37661
|
+
for (const step of plan.steps) {
|
|
37662
|
+
if (step.status === "done" || step.status === "skipped")
|
|
37532
37663
|
continue;
|
|
37533
|
-
const stepPaths = extractFileLikeTokens(stripUrls(
|
|
37664
|
+
const stepPaths = extractFileLikeTokens(stripUrls(step.description)).map((p) => p.toLowerCase());
|
|
37534
37665
|
if (stepPaths.length > 0 && stepPaths.some((s) => callPaths.some((c) => c.includes(s) || s.includes(c)))) {
|
|
37535
|
-
return t("ui.step_context", { id:
|
|
37666
|
+
return t("ui.step_context", { id: step.id, desc: truncate4(step.description) });
|
|
37536
37667
|
}
|
|
37537
37668
|
}
|
|
37538
37669
|
}
|
|
37539
|
-
|
|
37540
|
-
const step = plan.steps[cur];
|
|
37541
|
-
if (!step)
|
|
37542
|
-
return null;
|
|
37543
|
-
return t("ui.step_context", { id: step.id, desc: truncate4(step.description) });
|
|
37670
|
+
return null;
|
|
37544
37671
|
}
|
|
37545
37672
|
|
|
37546
37673
|
// src/cli/repl.ts
|
|
@@ -37623,10 +37750,10 @@ class Repl {
|
|
|
37623
37750
|
this.envReport = envReport;
|
|
37624
37751
|
this.execModule = execModule;
|
|
37625
37752
|
this.slog = new SessionLogger(sessionManager, logger4);
|
|
37626
|
-
this.configDir = configDir ||
|
|
37753
|
+
this.configDir = configDir || join52(homedir18(), ".mma");
|
|
37627
37754
|
this.baseDir = baseDir || process.cwd();
|
|
37628
37755
|
this.noAgentsMd = noAgentsMd === true;
|
|
37629
|
-
this.historyPath = historyPath ??
|
|
37756
|
+
this.historyPath = historyPath ?? join52(homedir18(), ".mma", "repl-history");
|
|
37630
37757
|
this.loadHistory();
|
|
37631
37758
|
this.rl = process.stdin.isTTY ? new LineEditor({
|
|
37632
37759
|
input: process.stdin,
|
|
@@ -37678,9 +37805,9 @@ class Repl {
|
|
|
37678
37805
|
}));
|
|
37679
37806
|
}
|
|
37680
37807
|
loadHistory() {
|
|
37681
|
-
if (
|
|
37808
|
+
if (existsSync59(this.historyPath)) {
|
|
37682
37809
|
try {
|
|
37683
|
-
const raw =
|
|
37810
|
+
const raw = readFileSync40(this.historyPath, "utf-8");
|
|
37684
37811
|
this.history = raw.split(`
|
|
37685
37812
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
37686
37813
|
} catch {
|
|
@@ -37690,7 +37817,7 @@ class Repl {
|
|
|
37690
37817
|
}
|
|
37691
37818
|
saveHistory() {
|
|
37692
37819
|
const allHistory = this.history.slice(-this.maxHistory);
|
|
37693
|
-
|
|
37820
|
+
writeFileSync23(this.historyPath, allHistory.join(`
|
|
37694
37821
|
`), "utf-8");
|
|
37695
37822
|
}
|
|
37696
37823
|
setupCompleter() {
|
|
@@ -37907,14 +38034,14 @@ ${t("image.clipboard_empty")}`));
|
|
|
37907
38034
|
` + pc2.green(t("repl.agent")));
|
|
37908
38035
|
const renderer = new Renderer({
|
|
37909
38036
|
spinner: this.config.ui?.spinner ?? true,
|
|
37910
|
-
toolStyle: this.config.ui?.toolStyle ?? "inline",
|
|
37911
38037
|
baseDir: this.baseDir
|
|
37912
38038
|
});
|
|
38039
|
+
renderer.showLoader();
|
|
37913
38040
|
const result = await this.agent.run(input, (c) => renderer.text(c), (m) => renderer.meta(m), (ev) => {
|
|
37914
38041
|
if (ev.type === "start") {
|
|
37915
38042
|
renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.execModule?.getActivePlan() ?? null, ev.tool, ev.args), ev.icon);
|
|
37916
38043
|
} else {
|
|
37917
|
-
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd
|
|
38044
|
+
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd);
|
|
37918
38045
|
if (ev.tool === "plan" || ev.tool === "todo") {
|
|
37919
38046
|
this.renderPlan(renderer);
|
|
37920
38047
|
}
|
|
@@ -37927,6 +38054,9 @@ ${t("image.clipboard_empty")}`));
|
|
|
37927
38054
|
}
|
|
37928
38055
|
});
|
|
37929
38056
|
renderer.flush();
|
|
38057
|
+
if (result.provider && result.model) {
|
|
38058
|
+
renderer.footer(result.model, result.provider, result.llmDurationMs ?? result.durationMs ?? 0);
|
|
38059
|
+
}
|
|
37930
38060
|
process.stdout.write(`
|
|
37931
38061
|
`);
|
|
37932
38062
|
this.logger?.logREPL(result.success ? "assistant" : "system", result.text?.slice(0, 400) || result.error || "");
|
|
@@ -38078,11 +38208,11 @@ ${t("image.clipboard_empty")}`));
|
|
|
38078
38208
|
row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
|
|
38079
38209
|
} else {
|
|
38080
38210
|
const agentsMdCandidates = [
|
|
38081
|
-
|
|
38082
|
-
|
|
38083
|
-
|
|
38211
|
+
join52(this.baseDir, "AGENTS.md"),
|
|
38212
|
+
join52(this.baseDir, ".mma", "AGENTS.md"),
|
|
38213
|
+
join52(this.configDir, "AGENTS.md")
|
|
38084
38214
|
];
|
|
38085
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
38215
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync59(p));
|
|
38086
38216
|
if (foundAgents.length > 0) {
|
|
38087
38217
|
for (const p of foundAgents) {
|
|
38088
38218
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -38093,7 +38223,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
38093
38223
|
}
|
|
38094
38224
|
const meta = this.sessionManager?.getActiveMeta();
|
|
38095
38225
|
if (meta) {
|
|
38096
|
-
const sessionPath =
|
|
38226
|
+
const sessionPath = join52(this.configDir, "sessions", meta.id);
|
|
38097
38227
|
row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
|
|
38098
38228
|
}
|
|
38099
38229
|
const isTty2 = process.stdout.isTTY === true;
|
|
@@ -38208,9 +38338,9 @@ init_setup();
|
|
|
38208
38338
|
init_config2();
|
|
38209
38339
|
init_i18n();
|
|
38210
38340
|
init_colors();
|
|
38211
|
-
import { existsSync as
|
|
38212
|
-
import { join as
|
|
38213
|
-
import { homedir as
|
|
38341
|
+
import { existsSync as existsSync60 } from "fs";
|
|
38342
|
+
import { join as join54, dirname as dirname25 } from "path";
|
|
38343
|
+
import { homedir as homedir20 } from "os";
|
|
38214
38344
|
|
|
38215
38345
|
// src/modules/updater/index.ts
|
|
38216
38346
|
init_checker();
|
|
@@ -38322,10 +38452,10 @@ ${t("cli.changelog_title", { version: result.latest })}
|
|
|
38322
38452
|
init_environment();
|
|
38323
38453
|
init_data_sanitizer();
|
|
38324
38454
|
init_i18n();
|
|
38325
|
-
import { appendFileSync as appendFileSync7, mkdirSync as
|
|
38326
|
-
import { join as
|
|
38327
|
-
import { homedir as
|
|
38328
|
-
var CRASH_LOG_DIR =
|
|
38455
|
+
import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync22 } from "fs";
|
|
38456
|
+
import { join as join53 } from "path";
|
|
38457
|
+
import { homedir as homedir19 } from "os";
|
|
38458
|
+
var CRASH_LOG_DIR = join53(homedir19(), ".mma", "logs");
|
|
38329
38459
|
var CRASH_LOG_FILE = "crash.jsonl";
|
|
38330
38460
|
function formatCrashEntry(type2, err) {
|
|
38331
38461
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -38335,13 +38465,13 @@ function formatCrashEntry(type2, err) {
|
|
|
38335
38465
|
type: type2,
|
|
38336
38466
|
message: sanitizeLogMessage(message),
|
|
38337
38467
|
stack: sanitizeLogMessage(stack),
|
|
38338
|
-
environment: collectEnvironment({ configDir:
|
|
38468
|
+
environment: collectEnvironment({ configDir: homedir19(), scanTools: false })
|
|
38339
38469
|
};
|
|
38340
38470
|
}
|
|
38341
38471
|
function writeCrashEntry(dir, entry) {
|
|
38342
38472
|
try {
|
|
38343
|
-
|
|
38344
|
-
appendFileSync7(
|
|
38473
|
+
mkdirSync22(dir, { recursive: true });
|
|
38474
|
+
appendFileSync7(join53(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
|
|
38345
38475
|
`, "utf-8");
|
|
38346
38476
|
} catch {}
|
|
38347
38477
|
}
|
|
@@ -38423,14 +38553,14 @@ async function main() {
|
|
|
38423
38553
|
}, null, 2));
|
|
38424
38554
|
process.stdout.write(`
|
|
38425
38555
|
`);
|
|
38426
|
-
await updater?.waitForIdle();
|
|
38556
|
+
await updater?.waitForIdle(1e4);
|
|
38427
38557
|
process.exit(result2.success ? 0 : 1);
|
|
38428
38558
|
}
|
|
38429
38559
|
const renderer = new Renderer({
|
|
38430
38560
|
spinner: config.ui?.spinner ?? true,
|
|
38431
|
-
toolStyle: config.ui?.toolStyle ?? "inline",
|
|
38432
38561
|
baseDir
|
|
38433
38562
|
});
|
|
38563
|
+
renderer.showLoader();
|
|
38434
38564
|
const result = await agent.run(prompt, (chunk) => renderer.text(chunk), (meta) => renderer.meta(meta), (ev) => {
|
|
38435
38565
|
if (ev.type === "start") {
|
|
38436
38566
|
renderer.toolStart(ev.tool, ev.args, undefined, ev.icon);
|
|
@@ -38445,14 +38575,17 @@ async function main() {
|
|
|
38445
38575
|
}
|
|
38446
38576
|
});
|
|
38447
38577
|
renderer.flush();
|
|
38578
|
+
if (result.provider && result.model) {
|
|
38579
|
+
renderer.footer(result.model, result.provider, result.llmDurationMs ?? result.durationMs ?? 0);
|
|
38580
|
+
}
|
|
38448
38581
|
const exitCode = printRunResult(result, () => renderer.flush());
|
|
38449
38582
|
agent.shutdown();
|
|
38450
38583
|
await updater?.waitForIdle();
|
|
38451
38584
|
process.exit(exitCode);
|
|
38452
38585
|
} else {
|
|
38453
|
-
const mmaDir =
|
|
38454
|
-
const legacyConfigPath =
|
|
38455
|
-
let hasAnyConfig =
|
|
38586
|
+
const mmaDir = join54(homedir20(), ".mma");
|
|
38587
|
+
const legacyConfigPath = join54(mmaDir, "config.json");
|
|
38588
|
+
let hasAnyConfig = existsSync60(legacyConfigPath);
|
|
38456
38589
|
if (!hasAnyConfig) {
|
|
38457
38590
|
try {
|
|
38458
38591
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
@@ -38515,7 +38648,7 @@ async function main() {
|
|
|
38515
38648
|
config.security.paths.denied = [];
|
|
38516
38649
|
}
|
|
38517
38650
|
}
|
|
38518
|
-
saveConfig(config, legacyConfigPath,
|
|
38651
|
+
saveConfig(config, legacyConfigPath, dirname25(legacyConfigPath));
|
|
38519
38652
|
await agent.reconfigure(config);
|
|
38520
38653
|
}
|
|
38521
38654
|
startAutoUpdate(config);
|