micro-models-agent 0.45.0 → 0.46.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +312 -312
- package/dist/cli/commands.js +323 -0
- package/dist/cli/completer.js +167 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/main.js +165 -0
- package/dist/cli/plugin-commands.js +36 -0
- package/dist/cli/repl-commands.js +661 -0
- package/dist/cli/repl.js +616 -0
- package/dist/cli/run-result.js +22 -0
- package/dist/cli/security-commands.js +164 -0
- package/dist/cli/setup.js +231 -0
- package/dist/config/config.js +249 -0
- package/dist/config/defaults.js +124 -0
- package/dist/config/experts.js +15 -0
- package/dist/config/index.js +3 -0
- package/dist/config/security.js +193 -0
- package/dist/config/types.js +1 -0
- package/dist/core/agent-moe.js +102 -0
- package/dist/core/agent.js +886 -0
- package/dist/core/bootstrap.js +404 -0
- package/dist/core/index.js +2 -0
- package/dist/core/prompt-builder.js +76 -0
- package/dist/core/session-logger.js +197 -0
- package/dist/core/types.js +1 -0
- package/dist/core/version.js +24 -0
- package/dist/core/workspace.js +76 -0
- package/dist/i18n/en.json +598 -0
- package/dist/i18n/index.js +46 -0
- package/dist/i18n/ru.json +598 -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 +359 -0
- package/dist/llm/orchestrator.js +198 -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 +143 -0
- package/dist/logger/file-log.js +151 -0
- package/dist/logger/index.js +1 -0
- package/dist/main.js +690 -168
- 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 +202 -202
- 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 +338 -0
- package/dist/modules/browser/snapshot.js +148 -0
- package/dist/modules/browser/types.js +12 -0
- package/dist/modules/certification/cli.js +174 -0
- package/dist/modules/certification/fact-checker.js +82 -0
- package/dist/modules/certification/loader.js +105 -0
- package/dist/modules/certification/manifest.js +50 -0
- package/dist/modules/certification/runner.js +159 -0
- package/dist/modules/certification/scenarios.js +124 -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 +162 -0
- package/dist/modules/context/history.js +15 -0
- package/dist/modules/context/index.js +1 -0
- package/dist/modules/context/manager.js +423 -0
- package/dist/modules/execution/audit-runners.js +152 -0
- package/dist/modules/execution/auditor.js +218 -0
- package/dist/modules/execution/execution-plugin.js +272 -0
- package/dist/modules/execution/index.js +8 -0
- package/dist/modules/execution/module.js +436 -0
- package/dist/modules/execution/moe-executor.js +291 -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 +157 -0
- package/dist/modules/execution/plan-tool.js +508 -0
- package/dist/modules/execution/plan-validator.js +153 -0
- package/dist/modules/execution/planner.js +90 -0
- package/dist/modules/execution/stuck-detector.js +510 -0
- package/dist/modules/execution/tracker.js +67 -0
- package/dist/modules/execution/types.js +1 -0
- package/dist/modules/execution/verifier.js +222 -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 +43 -0
- package/dist/modules/hallucination/factual.js +129 -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 +245 -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 +278 -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 +232 -0
- package/dist/modules/lsp/probe.js +76 -0
- package/dist/modules/lsp/project-root.js +32 -0
- package/dist/modules/lsp/startup-check.js +141 -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 +231 -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 +217 -0
- package/dist/modules/plugins/types.js +1 -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/registry.js +47 -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 +205 -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 +71 -0
- package/dist/modules/security/path-validator.js +207 -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 +32 -0
- package/dist/tools/attach-image.js +89 -0
- package/dist/tools/bash.js +496 -0
- package/dist/tools/browser.js +114 -0
- package/dist/tools/chunk-query.js +99 -0
- package/dist/tools/create-dir.js +55 -0
- package/dist/tools/delete-file.js +62 -0
- package/dist/tools/download-file.js +116 -0
- package/dist/tools/edit-file.js +79 -0
- package/dist/tools/enable-tools.js +58 -0
- package/dist/tools/executor.js +144 -0
- package/dist/tools/file-info.js +46 -0
- package/dist/tools/filter-tools.js +17 -0
- package/dist/tools/glob-tool.js +26 -0
- package/dist/tools/grep-tool.js +84 -0
- package/dist/tools/hidden-tools-block.js +37 -0
- package/dist/tools/index.js +78 -0
- package/dist/tools/list-dir.js +48 -0
- package/dist/tools/load-skill.js +42 -0
- package/dist/tools/mcp-call.js +68 -0
- package/dist/tools/move-file.js +85 -0
- package/dist/tools/path-utils.js +51 -0
- package/dist/tools/pipeline-run.js +144 -0
- package/dist/tools/preview.js +2 -0
- package/dist/tools/process-kill.js +29 -0
- package/dist/tools/process-list.js +36 -0
- package/dist/tools/process-log.js +45 -0
- package/dist/tools/question.js +140 -0
- package/dist/tools/read-file.js +91 -0
- package/dist/tools/recall.js +117 -0
- package/dist/tools/registry.js +47 -0
- package/dist/tools/remember.js +67 -0
- package/dist/tools/scope-check.js +30 -0
- package/dist/tools/search-history.js +84 -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 +86 -0
- package/dist/tools/web-fetch.js +98 -0
- package/dist/tools/web-search.js +78 -0
- package/dist/tools/write-file.js +81 -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 +703 -0
- package/dist/ui/line-math.js +69 -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 +209 -0
- package/dist/ui/spinner.js +70 -0
- package/dist/ui/table.js +144 -0
- package/package.json +48 -48
package/dist/main.js
CHANGED
|
@@ -2263,7 +2263,9 @@ var init_defaults = __esm(() => {
|
|
|
2263
2263
|
retry: {
|
|
2264
2264
|
maxRetries: 3,
|
|
2265
2265
|
baseDelay: 1000,
|
|
2266
|
-
maxDelay: 30000
|
|
2266
|
+
maxDelay: 30000,
|
|
2267
|
+
maxStreamRetries: 2,
|
|
2268
|
+
noDataTimeoutMs: 60000
|
|
2267
2269
|
},
|
|
2268
2270
|
maxToolIterations: 1000,
|
|
2269
2271
|
stuckThreshold: 6,
|
|
@@ -2396,6 +2398,14 @@ Use read_file on {path} to see the current content before editing — the target
|
|
|
2396
2398
|
"error.llm_retries": "LLM request failed after retries",
|
|
2397
2399
|
"error.llm_429": "Rate limit exceeded (HTTP 429) for {model} on {baseUrl}. The provider is throttling requests — free models are especially strict. Get an API key or switch to a paid/faster model: {baseUrl}",
|
|
2398
2400
|
"error.no_response_body": "No response body stream",
|
|
2401
|
+
"error.llm_stream_idle": "LLM stream stalled — no data for {timeout}ms",
|
|
2402
|
+
"error.llm_timeout": "LLM request timed out ({timeout}ms)",
|
|
2403
|
+
"env.runtime_node": "Running under Node (v{version}) — clipboard image paste, subagent performance and LSP spawn on Windows degrade. Install Bun (https://bun.sh) for full features.",
|
|
2404
|
+
"env.runtime_old": "Runtime version {version} is below the required engines {engine}.",
|
|
2405
|
+
"env.tool_missing": "Tool not found on PATH: {tool}",
|
|
2406
|
+
"env.playwright_missing": "Playwright package is not installed — the browser tool will fail. Install with: bun add playwright",
|
|
2407
|
+
"env.playwright_browsers_missing": "Playwright browsers not downloaded ({dir}). The browser tool will fail. Install with: bunx playwright install chromium",
|
|
2408
|
+
"env.crash_stderr": "MMA crashed ({type}): {message} — crash report written to ~/.mma/logs/crash.jsonl",
|
|
2399
2409
|
"session.started": "Session started: {id}",
|
|
2400
2410
|
"session.ended": "Session ended: {id}",
|
|
2401
2411
|
"session.not_found": "Session not found: {id}",
|
|
@@ -2779,6 +2789,19 @@ Available commands:`,
|
|
|
2779
2789
|
"repl.lsp_timeout": "timeout",
|
|
2780
2790
|
"repl.lsp_failed": "did not start",
|
|
2781
2791
|
"repl.lsp_unknown": "unknown",
|
|
2792
|
+
"repl.lsp": "LSP server management (status, restart, check)",
|
|
2793
|
+
"repl.lsp_usage": "Usage: /lsp [status|restart|check <path>]",
|
|
2794
|
+
"repl.lsp_not_available": "LSP module not available",
|
|
2795
|
+
"repl.lsp_status_header": "LSP Status:",
|
|
2796
|
+
"repl.lsp_enabled": "Enabled:",
|
|
2797
|
+
"repl.lsp_disabled_servers": "Disabled servers:",
|
|
2798
|
+
"repl.lsp_failure_counts": "Failure counts:",
|
|
2799
|
+
"repl.lsp_all_ok": "All servers operational",
|
|
2800
|
+
"repl.lsp_restarting": "Resetting LSP server state...",
|
|
2801
|
+
"repl.lsp_restarted": "LSP servers reset. Failed servers will be retried on next use.",
|
|
2802
|
+
"repl.lsp_check_usage": "Usage: /lsp check <file-or-directory>",
|
|
2803
|
+
"repl.lsp_checking": "Running LSP check on {path}...",
|
|
2804
|
+
"repl.lsp_check_error": "LSP check failed: {error}",
|
|
2782
2805
|
"repl.work_dir": "Dir:",
|
|
2783
2806
|
"repl.agents_label": "Instructions:",
|
|
2784
2807
|
"repl.not_found": "not found",
|
|
@@ -3059,6 +3082,14 @@ var init_ru = __esm(() => {
|
|
|
3059
3082
|
"error.llm_retries": "Запрос LLM не удался после повторов",
|
|
3060
3083
|
"error.llm_429": "Превышен лимит запросов (HTTP 429) для {model} на {baseUrl}. Провайдер ограничивает трафик — особенно строгие free-модели. Получите API-ключ или переключитесь на платную/быструю модель: {baseUrl}",
|
|
3061
3084
|
"error.no_response_body": "Нет потока тела ответа",
|
|
3085
|
+
"error.llm_stream_idle": "Поток LLM завис — нет данных {timeout}мс",
|
|
3086
|
+
"error.llm_timeout": "Время запроса LLM истекло ({timeout}мс)",
|
|
3087
|
+
"env.runtime_node": "Запущено под Node (v{version}) — вставка изображений из буфера и LSP на Windows работают урезанно. Установите Bun (https://bun.sh) для полного функционала.",
|
|
3088
|
+
"env.runtime_old": "Версия рантайма {version} ниже требуемой engines {engine}.",
|
|
3089
|
+
"env.tool_missing": "Инструмент не найден в PATH: {tool}",
|
|
3090
|
+
"env.playwright_missing": "Пакет Playwright не установлен — браузерный инструмент не будет работать. Установите: bun add playwright",
|
|
3091
|
+
"env.playwright_browsers_missing": "Браузеры Playwright не скачаны ({dir}). Браузерный инструмент не будет работать. Установите: bunx playwright install chromium",
|
|
3092
|
+
"env.crash_stderr": "MMA упал ({type}): {message} — отчёт о падении записан в ~/.mma/logs/crash.jsonl",
|
|
3062
3093
|
"session.started": "Сессия начата: {id}",
|
|
3063
3094
|
"session.ended": "Сессия завершена: {id}",
|
|
3064
3095
|
"session.not_found": "Сессия не найдена: {id}",
|
|
@@ -3437,6 +3468,19 @@ var init_ru = __esm(() => {
|
|
|
3437
3468
|
"repl.lsp_timeout": "таймаут",
|
|
3438
3469
|
"repl.lsp_failed": "не стартовал",
|
|
3439
3470
|
"repl.lsp_unknown": "неизвестно",
|
|
3471
|
+
"repl.lsp": "Управление LSP-серверами (status, restart, check)",
|
|
3472
|
+
"repl.lsp_usage": "Использование: /lsp [status|restart|check <путь>]",
|
|
3473
|
+
"repl.lsp_not_available": "Модуль LSP недоступен",
|
|
3474
|
+
"repl.lsp_status_header": "Статус LSP:",
|
|
3475
|
+
"repl.lsp_enabled": "Включён:",
|
|
3476
|
+
"repl.lsp_disabled_servers": "Отключённые серверы:",
|
|
3477
|
+
"repl.lsp_failure_counts": "Количество ошибок:",
|
|
3478
|
+
"repl.lsp_all_ok": "Все серверы работают",
|
|
3479
|
+
"repl.lsp_restarting": "Сброс состояния LSP-серверов...",
|
|
3480
|
+
"repl.lsp_restarted": "LSP-серверы сброшены. Упавшие серверы будут повторно запущены при следующем использовании.",
|
|
3481
|
+
"repl.lsp_check_usage": "Использование: /lsp check <файл-или-каталог>",
|
|
3482
|
+
"repl.lsp_checking": "Запуск LSP-проверки {path}...",
|
|
3483
|
+
"repl.lsp_check_error": "LSP-проверка не удалась: {error}",
|
|
3440
3484
|
"repl.work_dir": "Директория:",
|
|
3441
3485
|
"repl.agents_label": "Инструкции:",
|
|
3442
3486
|
"repl.not_found": "не найден",
|
|
@@ -4596,6 +4640,20 @@ class Logger {
|
|
|
4596
4640
|
}
|
|
4597
4641
|
return sanitized;
|
|
4598
4642
|
}
|
|
4643
|
+
logStructured(type, data) {
|
|
4644
|
+
const logTarget = this.sessionDir ?? this.logDir;
|
|
4645
|
+
if (!logTarget)
|
|
4646
|
+
return;
|
|
4647
|
+
try {
|
|
4648
|
+
appendFileSync2(join6(logTarget, "app.jsonl"), JSON.stringify({
|
|
4649
|
+
level: "info",
|
|
4650
|
+
ts: new Date().toISOString(),
|
|
4651
|
+
type,
|
|
4652
|
+
meta: this.sanitizeMeta(data)
|
|
4653
|
+
}) + `
|
|
4654
|
+
`, "utf-8");
|
|
4655
|
+
} catch {}
|
|
4656
|
+
}
|
|
4599
4657
|
}
|
|
4600
4658
|
var import_picocolors, LEVELS, LEVEL_COLORS;
|
|
4601
4659
|
var init_app_logger = __esm(() => {
|
|
@@ -5172,7 +5230,9 @@ class OpenAICompatProvider {
|
|
|
5172
5230
|
this.retryConfig = config.retry ?? {
|
|
5173
5231
|
maxRetries: 3,
|
|
5174
5232
|
baseDelay: 1000,
|
|
5175
|
-
maxDelay: 30000
|
|
5233
|
+
maxDelay: 30000,
|
|
5234
|
+
maxStreamRetries: 2,
|
|
5235
|
+
noDataTimeoutMs: 60000
|
|
5176
5236
|
};
|
|
5177
5237
|
this.rateLimiter = createRateLimiter(config.rateLimits);
|
|
5178
5238
|
}
|
|
@@ -5203,6 +5263,32 @@ class OpenAICompatProvider {
|
|
|
5203
5263
|
}
|
|
5204
5264
|
}
|
|
5205
5265
|
async* doStream(messages, tools, signal, options) {
|
|
5266
|
+
const { baseDelay, maxDelay, maxStreamRetries, noDataTimeoutMs } = this.retryConfig;
|
|
5267
|
+
const streamRetries = maxStreamRetries ?? 2;
|
|
5268
|
+
const idleTimeoutMs = noDataTimeoutMs ?? 60000;
|
|
5269
|
+
for (let attempt = 0;; attempt++) {
|
|
5270
|
+
let emitted = false;
|
|
5271
|
+
const onEmit = () => {
|
|
5272
|
+
emitted = true;
|
|
5273
|
+
};
|
|
5274
|
+
try {
|
|
5275
|
+
const sawDone = yield* this.streamOnce(messages, tools, signal, options, onEmit, idleTimeoutMs);
|
|
5276
|
+
if (sawDone || emitted)
|
|
5277
|
+
return;
|
|
5278
|
+
if (attempt >= streamRetries)
|
|
5279
|
+
return;
|
|
5280
|
+
} catch (err) {
|
|
5281
|
+
if (err?.name === "AbortError" || err?.llmTerminal || signal?.aborted)
|
|
5282
|
+
throw err;
|
|
5283
|
+
if (emitted || attempt >= streamRetries)
|
|
5284
|
+
throw err;
|
|
5285
|
+
}
|
|
5286
|
+
const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay);
|
|
5287
|
+
const jitter = Math.random() * baseDelay * 0.1;
|
|
5288
|
+
await this.sleep(delay + jitter, signal);
|
|
5289
|
+
}
|
|
5290
|
+
}
|
|
5291
|
+
async* streamOnce(messages, tools, signal, options, onEmit, idleTimeoutMs) {
|
|
5206
5292
|
const body = buildRequestBody({
|
|
5207
5293
|
model: this.model,
|
|
5208
5294
|
messages,
|
|
@@ -5218,8 +5304,11 @@ class OpenAICompatProvider {
|
|
|
5218
5304
|
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
5219
5305
|
}
|
|
5220
5306
|
const controller = new AbortController;
|
|
5221
|
-
|
|
5222
|
-
const timeoutId = setTimeout(() =>
|
|
5307
|
+
let timedOut = false;
|
|
5308
|
+
const timeoutId = setTimeout(() => {
|
|
5309
|
+
timedOut = true;
|
|
5310
|
+
controller.abort();
|
|
5311
|
+
}, REQUEST_TIMEOUT_MS);
|
|
5223
5312
|
const abortSignal = (() => {
|
|
5224
5313
|
if (!signal)
|
|
5225
5314
|
return controller.signal;
|
|
@@ -5232,20 +5321,31 @@ class OpenAICompatProvider {
|
|
|
5232
5321
|
return controller.signal;
|
|
5233
5322
|
}
|
|
5234
5323
|
})();
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5324
|
+
let response;
|
|
5325
|
+
try {
|
|
5326
|
+
response = await this.fetchWithRetry(`${this.config.baseUrl}/chat/completions`, {
|
|
5327
|
+
method: "POST",
|
|
5328
|
+
headers,
|
|
5329
|
+
body: JSON.stringify(body),
|
|
5330
|
+
signal: abortSignal
|
|
5331
|
+
});
|
|
5332
|
+
} catch (err) {
|
|
5333
|
+
if (err?.name === "AbortError")
|
|
5334
|
+
throw err;
|
|
5335
|
+
const wrapped = err instanceof Error ? err : new Error(String(err));
|
|
5336
|
+
wrapped.llmTerminal = true;
|
|
5337
|
+
throw wrapped;
|
|
5338
|
+
}
|
|
5241
5339
|
if (!response.ok) {
|
|
5242
5340
|
clearTimeout(timeoutId);
|
|
5243
5341
|
const errorText = await response.text();
|
|
5244
|
-
|
|
5342
|
+
const err = new Error(t("error.llm_api", {
|
|
5245
5343
|
status: response.status,
|
|
5246
5344
|
statusText: response.statusText,
|
|
5247
5345
|
errorText
|
|
5248
5346
|
}));
|
|
5347
|
+
err.llmTerminal = true;
|
|
5348
|
+
throw err;
|
|
5249
5349
|
}
|
|
5250
5350
|
const reader = response.body?.getReader();
|
|
5251
5351
|
if (!reader) {
|
|
@@ -5256,9 +5356,29 @@ class OpenAICompatProvider {
|
|
|
5256
5356
|
let buffer = "";
|
|
5257
5357
|
const toolCallAccs = new Map;
|
|
5258
5358
|
let usage;
|
|
5359
|
+
let sawDone = false;
|
|
5360
|
+
const readIdle = () => new Promise((resolve, reject) => {
|
|
5361
|
+
const idleTimer = setTimeout(() => {
|
|
5362
|
+
timedOut = true;
|
|
5363
|
+
controller.abort();
|
|
5364
|
+
}, idleTimeoutMs);
|
|
5365
|
+
reader.read().then((result) => {
|
|
5366
|
+
clearTimeout(idleTimer);
|
|
5367
|
+
if (timedOut)
|
|
5368
|
+
reject(new Error(t("error.llm_stream_idle", { timeout: idleTimeoutMs })));
|
|
5369
|
+
else
|
|
5370
|
+
resolve(result);
|
|
5371
|
+
}, (err) => {
|
|
5372
|
+
clearTimeout(idleTimer);
|
|
5373
|
+
if (timedOut)
|
|
5374
|
+
reject(new Error(t("error.llm_stream_idle", { timeout: idleTimeoutMs })));
|
|
5375
|
+
else
|
|
5376
|
+
reject(err);
|
|
5377
|
+
});
|
|
5378
|
+
});
|
|
5259
5379
|
try {
|
|
5260
5380
|
while (true) {
|
|
5261
|
-
const { done, value } = await
|
|
5381
|
+
const { done, value } = await readIdle();
|
|
5262
5382
|
if (done)
|
|
5263
5383
|
break;
|
|
5264
5384
|
buffer += decoder.decode(value, { stream: true });
|
|
@@ -5270,8 +5390,10 @@ class OpenAICompatProvider {
|
|
|
5270
5390
|
if (!trimmed || !trimmed.startsWith("data: "))
|
|
5271
5391
|
continue;
|
|
5272
5392
|
const data = trimmed.slice(6);
|
|
5273
|
-
if (data === "[DONE]")
|
|
5393
|
+
if (data === "[DONE]") {
|
|
5394
|
+
sawDone = true;
|
|
5274
5395
|
continue;
|
|
5396
|
+
}
|
|
5275
5397
|
try {
|
|
5276
5398
|
const parsed = JSON.parse(data);
|
|
5277
5399
|
const choice = parsed.choices?.[0];
|
|
@@ -5288,6 +5410,7 @@ class OpenAICompatProvider {
|
|
|
5288
5410
|
const delta = choice.delta || {};
|
|
5289
5411
|
const finishReason = choice.finish_reason;
|
|
5290
5412
|
if (delta.reasoning_content) {
|
|
5413
|
+
onEmit();
|
|
5291
5414
|
yield { type: "reasoning", content: delta.reasoning_content };
|
|
5292
5415
|
}
|
|
5293
5416
|
if (delta.tool_calls) {
|
|
@@ -5307,11 +5430,13 @@ class OpenAICompatProvider {
|
|
|
5307
5430
|
}
|
|
5308
5431
|
}
|
|
5309
5432
|
if (delta.content) {
|
|
5433
|
+
onEmit();
|
|
5310
5434
|
yield { type: "text", content: delta.content };
|
|
5311
5435
|
}
|
|
5312
5436
|
if (finishReason === "tool_calls" && toolCallAccs.size > 0) {
|
|
5313
5437
|
for (const [, acc] of toolCallAccs) {
|
|
5314
5438
|
if (acc.name) {
|
|
5439
|
+
onEmit();
|
|
5315
5440
|
yield {
|
|
5316
5441
|
type: "tool_call",
|
|
5317
5442
|
toolCall: {
|
|
@@ -5328,12 +5453,14 @@ class OpenAICompatProvider {
|
|
|
5328
5453
|
}
|
|
5329
5454
|
}
|
|
5330
5455
|
if (usage) {
|
|
5456
|
+
onEmit();
|
|
5331
5457
|
yield { type: "done", usage };
|
|
5332
5458
|
}
|
|
5333
5459
|
} finally {
|
|
5334
5460
|
clearTimeout(timeoutId);
|
|
5335
5461
|
reader.releaseLock();
|
|
5336
5462
|
}
|
|
5463
|
+
return sawDone;
|
|
5337
5464
|
}
|
|
5338
5465
|
async doNonStreaming(messages, tools, signal, options) {
|
|
5339
5466
|
const body = buildRequestBody({
|
|
@@ -5350,12 +5477,30 @@ class OpenAICompatProvider {
|
|
|
5350
5477
|
if (this.config.apiKey && this.config.apiKey !== "not-needed") {
|
|
5351
5478
|
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
5352
5479
|
}
|
|
5480
|
+
const controller = new AbortController;
|
|
5481
|
+
let timedOut = false;
|
|
5482
|
+
const timeoutId = setTimeout(() => {
|
|
5483
|
+
timedOut = true;
|
|
5484
|
+
controller.abort();
|
|
5485
|
+
}, REQUEST_TIMEOUT_MS);
|
|
5486
|
+
const abortSignal = (() => {
|
|
5487
|
+
if (!signal)
|
|
5488
|
+
return controller.signal;
|
|
5489
|
+
try {
|
|
5490
|
+
return AbortSignal.any([controller.signal, signal]);
|
|
5491
|
+
} catch {
|
|
5492
|
+
signal.addEventListener("abort", () => controller.abort(), {
|
|
5493
|
+
once: true
|
|
5494
|
+
});
|
|
5495
|
+
return controller.signal;
|
|
5496
|
+
}
|
|
5497
|
+
})();
|
|
5353
5498
|
try {
|
|
5354
5499
|
const response = await this.fetchWithRetry(`${this.config.baseUrl}/chat/completions`, {
|
|
5355
5500
|
method: "POST",
|
|
5356
5501
|
headers,
|
|
5357
5502
|
body: JSON.stringify(body),
|
|
5358
|
-
signal
|
|
5503
|
+
signal: abortSignal
|
|
5359
5504
|
});
|
|
5360
5505
|
if (!response.ok) {
|
|
5361
5506
|
const errorText = await response.text();
|
|
@@ -5402,7 +5547,12 @@ class OpenAICompatProvider {
|
|
|
5402
5547
|
}
|
|
5403
5548
|
return chunks;
|
|
5404
5549
|
} catch (err) {
|
|
5550
|
+
if (timedOut && err?.name === "AbortError") {
|
|
5551
|
+
throw new Error(t("error.llm_timeout", { timeout: REQUEST_TIMEOUT_MS }));
|
|
5552
|
+
}
|
|
5405
5553
|
throw err instanceof Error ? err : new Error(String(err));
|
|
5554
|
+
} finally {
|
|
5555
|
+
clearTimeout(timeoutId);
|
|
5406
5556
|
}
|
|
5407
5557
|
}
|
|
5408
5558
|
countTokens(text) {
|
|
@@ -5486,6 +5636,7 @@ class OpenAICompatProvider {
|
|
|
5486
5636
|
});
|
|
5487
5637
|
}
|
|
5488
5638
|
}
|
|
5639
|
+
var REQUEST_TIMEOUT_MS = 120000;
|
|
5489
5640
|
var init_openai_compat = __esm(() => {
|
|
5490
5641
|
init_token_counter();
|
|
5491
5642
|
init_i18n();
|
|
@@ -11587,6 +11738,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11587
11738
|
onPhase?.(phase);
|
|
11588
11739
|
}
|
|
11589
11740
|
async run(input, onChunk, onMeta, onTool, onPhase) {
|
|
11741
|
+
this.shutdownRequested = false;
|
|
11590
11742
|
this.setScope();
|
|
11591
11743
|
const {
|
|
11592
11744
|
config,
|
|
@@ -12259,7 +12411,6 @@ ${warnLine}
|
|
|
12259
12411
|
if (killed > 0) {
|
|
12260
12412
|
logger.info(`Killed ${killed} background process(es) on shutdown`);
|
|
12261
12413
|
}
|
|
12262
|
-
logger.closeSessionLog();
|
|
12263
12414
|
pluginManager.runOnSessionEnd({
|
|
12264
12415
|
logger,
|
|
12265
12416
|
sessionManager: sessionManager?.getActiveMeta(),
|
|
@@ -19915,6 +20066,10 @@ import { resolve as resolve20 } from "path";
|
|
|
19915
20066
|
import { platform as platform8 } from "os";
|
|
19916
20067
|
|
|
19917
20068
|
class LspClient {
|
|
20069
|
+
logger = null;
|
|
20070
|
+
setLogger(logger) {
|
|
20071
|
+
this.logger = logger;
|
|
20072
|
+
}
|
|
19918
20073
|
process = null;
|
|
19919
20074
|
requestId = 0;
|
|
19920
20075
|
pending = new Map;
|
|
@@ -19974,11 +20129,25 @@ class LspClient {
|
|
|
19974
20129
|
try {
|
|
19975
20130
|
await this.sendRequest("initialize", initParams, timeout);
|
|
19976
20131
|
} catch (e) {
|
|
20132
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
20133
|
+
this.logger?.warn(`LSP initialize failed (attempt 1): ${msg}`, {
|
|
20134
|
+
command: config.command,
|
|
20135
|
+
projectRoot
|
|
20136
|
+
});
|
|
19977
20137
|
if (!(e instanceof Error) || !e.message.includes("initialize"))
|
|
19978
20138
|
throw e;
|
|
19979
20139
|
await this.shutdown();
|
|
19980
20140
|
await this.startServer(config, projectRoot);
|
|
19981
|
-
|
|
20141
|
+
try {
|
|
20142
|
+
await this.sendRequest("initialize", initParams, timeout);
|
|
20143
|
+
} catch (retryErr) {
|
|
20144
|
+
const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
|
|
20145
|
+
this.logger?.error(`LSP initialize failed (attempt 2, giving up): ${retryMsg}`, {
|
|
20146
|
+
command: config.command,
|
|
20147
|
+
projectRoot
|
|
20148
|
+
});
|
|
20149
|
+
throw retryErr;
|
|
20150
|
+
}
|
|
19982
20151
|
}
|
|
19983
20152
|
this.initialized = true;
|
|
19984
20153
|
}
|
|
@@ -20016,8 +20185,11 @@ class LspClient {
|
|
|
20016
20185
|
});
|
|
20017
20186
|
this.process = proc;
|
|
20018
20187
|
setTimeout(() => {
|
|
20019
|
-
if (!this.initialized && this.process)
|
|
20020
|
-
|
|
20188
|
+
if (!this.initialized && this.process) {
|
|
20189
|
+
const msg = "LSP server start timeout";
|
|
20190
|
+
this.logger?.error(msg, { command: config.command, projectRoot, timeout: config.timeout ?? 1e4 });
|
|
20191
|
+
reject(new Error(msg));
|
|
20192
|
+
}
|
|
20021
20193
|
}, config.timeout ?? 1e4);
|
|
20022
20194
|
});
|
|
20023
20195
|
}
|
|
@@ -20056,7 +20228,9 @@ class LspClient {
|
|
|
20056
20228
|
try {
|
|
20057
20229
|
const msg = JSON.parse(body);
|
|
20058
20230
|
this.handleMessage(msg);
|
|
20059
|
-
} catch {
|
|
20231
|
+
} catch (e) {
|
|
20232
|
+
this.logger?.debug(`LSP JSON parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
20233
|
+
}
|
|
20060
20234
|
}
|
|
20061
20235
|
}
|
|
20062
20236
|
handleMessage(msg) {
|
|
@@ -20094,7 +20268,9 @@ class LspClient {
|
|
|
20094
20268
|
setTimeout(() => {
|
|
20095
20269
|
if (this.pending.has(id)) {
|
|
20096
20270
|
this.pending.delete(id);
|
|
20097
|
-
|
|
20271
|
+
const msg = `LSP request timeout: ${method}`;
|
|
20272
|
+
this.logger?.warn(msg, { method, timeout });
|
|
20273
|
+
reject(new Error(msg));
|
|
20098
20274
|
}
|
|
20099
20275
|
}, timeout);
|
|
20100
20276
|
});
|
|
@@ -20104,27 +20280,37 @@ class LspClient {
|
|
|
20104
20280
|
this.write(message);
|
|
20105
20281
|
}
|
|
20106
20282
|
write(message) {
|
|
20107
|
-
if (!this.process?.stdin?.writable)
|
|
20283
|
+
if (!this.process?.stdin?.writable) {
|
|
20284
|
+
this.logger?.debug("LSP write failed: process stdin not writable");
|
|
20108
20285
|
return;
|
|
20286
|
+
}
|
|
20109
20287
|
const header = `Content-Length: ${Buffer.byteLength(message)}\r
|
|
20110
20288
|
\r
|
|
20111
20289
|
`;
|
|
20112
20290
|
try {
|
|
20113
20291
|
this.process.stdin.write(header + message);
|
|
20114
|
-
} catch {
|
|
20292
|
+
} catch (e) {
|
|
20293
|
+
this.logger?.debug(`LSP write error: ${e instanceof Error ? e.message : String(e)}`);
|
|
20294
|
+
}
|
|
20115
20295
|
}
|
|
20116
20296
|
async shutdown() {
|
|
20117
20297
|
try {
|
|
20118
20298
|
if (this.process && this.initialized && this.process.stdin?.writable) {
|
|
20119
|
-
this.sendRequest("shutdown", null, 3000).catch(() => {
|
|
20299
|
+
this.sendRequest("shutdown", null, 3000).catch((e) => {
|
|
20300
|
+
this.logger?.debug(`LSP shutdown request failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
20301
|
+
});
|
|
20120
20302
|
this.sendNotification("exit", null);
|
|
20121
20303
|
await new Promise((r) => setTimeout(r, 200));
|
|
20122
20304
|
}
|
|
20123
|
-
} catch
|
|
20305
|
+
} catch (e) {
|
|
20306
|
+
this.logger?.debug(`LSP shutdown error: ${e instanceof Error ? e.message : String(e)}`);
|
|
20307
|
+
} finally {
|
|
20124
20308
|
if (this.process) {
|
|
20125
20309
|
try {
|
|
20126
20310
|
killTree(this.process);
|
|
20127
|
-
} catch {
|
|
20311
|
+
} catch (e) {
|
|
20312
|
+
this.logger?.debug(`LSP killTree error: ${e instanceof Error ? e.message : String(e)}`);
|
|
20313
|
+
}
|
|
20128
20314
|
this.process = null;
|
|
20129
20315
|
}
|
|
20130
20316
|
this.initialized = false;
|
|
@@ -20232,9 +20418,26 @@ class LspModule {
|
|
|
20232
20418
|
client;
|
|
20233
20419
|
failuresByServer = new Map;
|
|
20234
20420
|
disabledServers = new Set;
|
|
20235
|
-
|
|
20421
|
+
logger = null;
|
|
20422
|
+
constructor(config, client, logger) {
|
|
20236
20423
|
this.config = { ...DEFAULT_LSP_CONFIG, ...config };
|
|
20237
20424
|
this.client = client ?? new LspClient;
|
|
20425
|
+
this.logger = logger ?? null;
|
|
20426
|
+
this.client.setLogger(this.logger);
|
|
20427
|
+
}
|
|
20428
|
+
setLogger(logger) {
|
|
20429
|
+
this.logger = logger;
|
|
20430
|
+
this.client.setLogger(logger);
|
|
20431
|
+
}
|
|
20432
|
+
resetDisabledServers() {
|
|
20433
|
+
this.failuresByServer.clear();
|
|
20434
|
+
this.disabledServers.clear();
|
|
20435
|
+
}
|
|
20436
|
+
getDisabledServers() {
|
|
20437
|
+
return Array.from(this.disabledServers);
|
|
20438
|
+
}
|
|
20439
|
+
getFailureCounts() {
|
|
20440
|
+
return new Map(this.failuresByServer);
|
|
20238
20441
|
}
|
|
20239
20442
|
isLspDisabled() {
|
|
20240
20443
|
return this.disabledServers.size > 0;
|
|
@@ -20505,7 +20708,9 @@ async function runCheck(config, baseDir, deps) {
|
|
|
20505
20708
|
lines.push(formatStartupError(file, baseDir, d));
|
|
20506
20709
|
}
|
|
20507
20710
|
}
|
|
20508
|
-
} catch {
|
|
20711
|
+
} catch (e) {
|
|
20712
|
+
deps.logger?.debug(`Startup LSP check failed for ${file}: ${e instanceof Error ? e.message : String(e)}`);
|
|
20713
|
+
}
|
|
20509
20714
|
}
|
|
20510
20715
|
if (checked === 0 || lines.length === 0)
|
|
20511
20716
|
return null;
|
|
@@ -21395,15 +21600,197 @@ function readMmaVersion() {
|
|
|
21395
21600
|
}
|
|
21396
21601
|
var init_version = () => {};
|
|
21397
21602
|
|
|
21603
|
+
// src/core/environment.ts
|
|
21604
|
+
import { existsSync as existsSync44, readFileSync as readFileSync27, readdirSync as readdirSync15 } from "fs";
|
|
21605
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
21606
|
+
import { createRequire as createRequire2 } from "module";
|
|
21607
|
+
import { join as join37, dirname as dirname14 } from "path";
|
|
21608
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
21609
|
+
import { arch, homedir as homedir11, hostname as hostname2, platform as platform9, release } from "os";
|
|
21610
|
+
import { env as env2 } from "process";
|
|
21611
|
+
function readEngineRequirement() {
|
|
21612
|
+
const here = dirname14(fileURLToPath3(import.meta.url));
|
|
21613
|
+
const candidates = [join37(here, "..", "..", "package.json"), join37(here, "..", "package.json")];
|
|
21614
|
+
for (const p of candidates) {
|
|
21615
|
+
if (!existsSync44(p))
|
|
21616
|
+
continue;
|
|
21617
|
+
try {
|
|
21618
|
+
const raw = JSON.parse(readFileSync27(p, "utf8"));
|
|
21619
|
+
if (raw.engines?.node)
|
|
21620
|
+
return String(raw.engines.node);
|
|
21621
|
+
} catch {}
|
|
21622
|
+
}
|
|
21623
|
+
return ">=20";
|
|
21624
|
+
}
|
|
21625
|
+
function satisfiesMinimum(version, requirement) {
|
|
21626
|
+
const minMatch = requirement.match(/(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
|
|
21627
|
+
if (!minMatch)
|
|
21628
|
+
return true;
|
|
21629
|
+
const min = [
|
|
21630
|
+
parseInt(minMatch[1], 10),
|
|
21631
|
+
minMatch[2] ? parseInt(minMatch[2], 10) : 0,
|
|
21632
|
+
minMatch[3] ? parseInt(minMatch[3], 10) : 0
|
|
21633
|
+
];
|
|
21634
|
+
const parts = version.replace(/^v/i, "").split(".");
|
|
21635
|
+
const got = [
|
|
21636
|
+
parts[0] ? parseInt(parts[0], 10) : 0,
|
|
21637
|
+
parts[1] ? parseInt(parts[1], 10) : 0,
|
|
21638
|
+
parts[2] ? parseInt(parts[2], 10) : 0
|
|
21639
|
+
];
|
|
21640
|
+
for (let i = 0;i < 3; i++) {
|
|
21641
|
+
if (got[i] > min[i])
|
|
21642
|
+
return true;
|
|
21643
|
+
if (got[i] < min[i])
|
|
21644
|
+
return false;
|
|
21645
|
+
}
|
|
21646
|
+
return true;
|
|
21647
|
+
}
|
|
21648
|
+
function detectRuntime() {
|
|
21649
|
+
const bun = globalThis.Bun;
|
|
21650
|
+
const isBun = typeof bun !== "undefined" && typeof bun?.version !== "undefined";
|
|
21651
|
+
const engine2 = readEngineRequirement();
|
|
21652
|
+
const runtime = isBun ? "bun" : "node";
|
|
21653
|
+
const runtimeVersion = isBun ? String(bun.version) : process.version;
|
|
21654
|
+
return {
|
|
21655
|
+
runtime,
|
|
21656
|
+
runtimeVersion,
|
|
21657
|
+
nodeVersion: process.version,
|
|
21658
|
+
engine: engine2,
|
|
21659
|
+
engineOk: satisfiesMinimum(process.version, engine2)
|
|
21660
|
+
};
|
|
21661
|
+
}
|
|
21662
|
+
function toolVersion(cmd) {
|
|
21663
|
+
try {
|
|
21664
|
+
const res = spawnSync2(cmd, ["--version"], {
|
|
21665
|
+
encoding: "utf8",
|
|
21666
|
+
timeout: 3000,
|
|
21667
|
+
windowsHide: true,
|
|
21668
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
21669
|
+
});
|
|
21670
|
+
if (res.error || res.status !== 0)
|
|
21671
|
+
return "missing";
|
|
21672
|
+
const out = ((res.stdout || "") + (res.stderr || "")).trim();
|
|
21673
|
+
return out.split(/\r?\n/)[0].slice(0, 40) || "ok";
|
|
21674
|
+
} catch {
|
|
21675
|
+
return "missing";
|
|
21676
|
+
}
|
|
21677
|
+
}
|
|
21678
|
+
function playwrightBrowsersDir() {
|
|
21679
|
+
if (process.env.PLAYWRIGHT_BROWSERS_PATH)
|
|
21680
|
+
return process.env.PLAYWRIGHT_BROWSERS_PATH;
|
|
21681
|
+
return process.platform === "win32" ? join37(homedir11(), "AppData", "Local", "ms-playwright") : join37(homedir11(), ".cache", "ms-playwright");
|
|
21682
|
+
}
|
|
21683
|
+
function playwrightInfo() {
|
|
21684
|
+
let installed = false;
|
|
21685
|
+
let version = "";
|
|
21686
|
+
const browsersDir = playwrightBrowsersDir();
|
|
21687
|
+
try {
|
|
21688
|
+
const require2 = createRequire2(import.meta.url);
|
|
21689
|
+
const pkgPath = require2.resolve("playwright/package.json");
|
|
21690
|
+
installed = existsSync44(pkgPath);
|
|
21691
|
+
version = JSON.parse(readFileSync27(pkgPath, "utf8")).version || "";
|
|
21692
|
+
} catch {
|
|
21693
|
+
installed = false;
|
|
21694
|
+
}
|
|
21695
|
+
let browsersInstalled = false;
|
|
21696
|
+
try {
|
|
21697
|
+
if (existsSync44(browsersDir)) {
|
|
21698
|
+
browsersInstalled = readdirSync15(browsersDir).some((d) => /chrom/i.test(d));
|
|
21699
|
+
}
|
|
21700
|
+
} catch {
|
|
21701
|
+
browsersInstalled = false;
|
|
21702
|
+
}
|
|
21703
|
+
return { installed, version, browsersDir, browsersInstalled };
|
|
21704
|
+
}
|
|
21705
|
+
function checkEnvironmentRequirements(report) {
|
|
21706
|
+
const warnings = [];
|
|
21707
|
+
if (report.runtime.runtime === "node") {
|
|
21708
|
+
warnings.push(t("env.runtime_node", { version: report.runtime.nodeVersion }));
|
|
21709
|
+
}
|
|
21710
|
+
if (!report.runtime.engineOk) {
|
|
21711
|
+
warnings.push(t("env.runtime_old", {
|
|
21712
|
+
version: report.runtime.nodeVersion,
|
|
21713
|
+
engine: report.runtime.engine
|
|
21714
|
+
}));
|
|
21715
|
+
}
|
|
21716
|
+
if (report.tools.bun === "missing") {
|
|
21717
|
+
warnings.push(t("env.tool_missing", { tool: "bun" }));
|
|
21718
|
+
}
|
|
21719
|
+
if (report.tools.git === "missing") {
|
|
21720
|
+
warnings.push(t("env.tool_missing", { tool: "git" }));
|
|
21721
|
+
}
|
|
21722
|
+
if (report.features.browser && report.playwright) {
|
|
21723
|
+
if (!report.playwright.installed) {
|
|
21724
|
+
warnings.push(t("env.playwright_missing"));
|
|
21725
|
+
} else if (!report.playwright.browsersInstalled) {
|
|
21726
|
+
warnings.push(t("env.playwright_browsers_missing", { dir: report.playwright.browsersDir }));
|
|
21727
|
+
}
|
|
21728
|
+
}
|
|
21729
|
+
return warnings;
|
|
21730
|
+
}
|
|
21731
|
+
function collectEnvironment(opts) {
|
|
21732
|
+
const runtime = detectRuntime();
|
|
21733
|
+
const tools = {};
|
|
21734
|
+
if (opts.scanTools) {
|
|
21735
|
+
for (const tool of TOOL_CHECKS)
|
|
21736
|
+
tools[tool] = toolVersion(tool);
|
|
21737
|
+
}
|
|
21738
|
+
const provider = opts.config ? {
|
|
21739
|
+
model: opts.config.model,
|
|
21740
|
+
baseUrl: sanitizeUrl(opts.config.provider?.baseUrl || ""),
|
|
21741
|
+
contextWindow: opts.config.contextWindow,
|
|
21742
|
+
retry: {
|
|
21743
|
+
maxRetries: opts.config.retry?.maxRetries ?? 0,
|
|
21744
|
+
baseDelay: opts.config.retry?.baseDelay ?? 0,
|
|
21745
|
+
maxDelay: opts.config.retry?.maxDelay ?? 0,
|
|
21746
|
+
maxStreamRetries: opts.config.retry?.maxStreamRetries ?? 0,
|
|
21747
|
+
noDataTimeoutMs: opts.config.retry?.noDataTimeoutMs ?? 0
|
|
21748
|
+
}
|
|
21749
|
+
} : null;
|
|
21750
|
+
const report = {
|
|
21751
|
+
ts: new Date().toISOString(),
|
|
21752
|
+
mmaVersion: readMmaVersion(),
|
|
21753
|
+
runtime,
|
|
21754
|
+
os: {
|
|
21755
|
+
platform: platform9(),
|
|
21756
|
+
arch: arch(),
|
|
21757
|
+
release: release(),
|
|
21758
|
+
hostname: hostname2(),
|
|
21759
|
+
shell: env2.SHELL || env2.ComSpec || "unknown",
|
|
21760
|
+
home: homedir11(),
|
|
21761
|
+
cwd: process.cwd()
|
|
21762
|
+
},
|
|
21763
|
+
paths: { configDir: opts.configDir, baseDir: opts.baseDir || process.cwd() },
|
|
21764
|
+
tools,
|
|
21765
|
+
provider,
|
|
21766
|
+
features: { browser: Boolean(opts.config?.browser?.enabled) },
|
|
21767
|
+
playwright: playwrightInfo(),
|
|
21768
|
+
warnings: []
|
|
21769
|
+
};
|
|
21770
|
+
report.warnings = checkEnvironmentRequirements(report);
|
|
21771
|
+
return report;
|
|
21772
|
+
}
|
|
21773
|
+
function logEnvironment(report, logger) {
|
|
21774
|
+
logger.info(`Environment: ${report.os.platform} ${report.os.arch} | ${report.runtime.runtime} ${report.runtime.runtimeVersion} (node ${report.runtime.nodeVersion}) | mma ${report.mmaVersion} | ${report.provider?.model ?? "no provider"}`);
|
|
21775
|
+
logger.logStructured("environment", report);
|
|
21776
|
+
}
|
|
21777
|
+
var TOOL_CHECKS;
|
|
21778
|
+
var init_environment = __esm(() => {
|
|
21779
|
+
init_version();
|
|
21780
|
+
init_network_validator();
|
|
21781
|
+
init_i18n();
|
|
21782
|
+
TOOL_CHECKS = ["bun", "node", "git", "python"];
|
|
21783
|
+
});
|
|
21784
|
+
|
|
21398
21785
|
// src/core/bootstrap.ts
|
|
21399
21786
|
var exports_bootstrap = {};
|
|
21400
21787
|
__export(exports_bootstrap, {
|
|
21401
21788
|
buildSystemInfo: () => buildSystemInfo,
|
|
21402
21789
|
bootstrap: () => bootstrap
|
|
21403
21790
|
});
|
|
21404
|
-
import { homedir as
|
|
21405
|
-
import { join as
|
|
21406
|
-
import { existsSync as
|
|
21791
|
+
import { homedir as homedir12 } from "os";
|
|
21792
|
+
import { join as join38, resolve as resolve23 } from "path";
|
|
21793
|
+
import { existsSync as existsSync45, readFileSync as readFileSync28, writeFileSync as writeFileSync15 } from "fs";
|
|
21407
21794
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
21408
21795
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
21409
21796
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -21429,8 +21816,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
21429
21816
|
`);
|
|
21430
21817
|
}
|
|
21431
21818
|
async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
21432
|
-
const dir = configDir ||
|
|
21433
|
-
const projectConfigPath = projectDir ?
|
|
21819
|
+
const dir = configDir || join38(homedir12(), ".mma");
|
|
21820
|
+
const projectConfigPath = projectDir ? join38(projectDir, ".mmrc") : join38(process.cwd(), ".mmrc");
|
|
21434
21821
|
const config = loadConfig({ configDir: dir, projectConfigPath });
|
|
21435
21822
|
setLocale(config.locale);
|
|
21436
21823
|
try {
|
|
@@ -21440,7 +21827,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21440
21827
|
}
|
|
21441
21828
|
} catch {}
|
|
21442
21829
|
const logger = new Logger(config.logLevel);
|
|
21443
|
-
logger.setLogDir(
|
|
21830
|
+
logger.setLogDir(join38(dir, "logs"));
|
|
21444
21831
|
logger.debug("MMA bootstrap", {
|
|
21445
21832
|
version: config.version,
|
|
21446
21833
|
model: config.model
|
|
@@ -21462,7 +21849,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21462
21849
|
logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
|
|
21463
21850
|
}
|
|
21464
21851
|
}
|
|
21465
|
-
const profile = new UserProfile(
|
|
21852
|
+
const profile = new UserProfile(join38(dir));
|
|
21466
21853
|
profile.load() || profile.collect();
|
|
21467
21854
|
profile.save();
|
|
21468
21855
|
const llmProvider = new OpenAICompatProvider({
|
|
@@ -21474,7 +21861,17 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21474
21861
|
rateLimits: config.security?.rateLimits
|
|
21475
21862
|
});
|
|
21476
21863
|
const baseDir = projectDir ? resolve23(projectDir) : process.cwd();
|
|
21477
|
-
const
|
|
21864
|
+
const envReport = collectEnvironment({
|
|
21865
|
+
configDir: dir,
|
|
21866
|
+
baseDir,
|
|
21867
|
+
config,
|
|
21868
|
+
scanTools: true
|
|
21869
|
+
});
|
|
21870
|
+
logEnvironment(envReport, logger);
|
|
21871
|
+
for (const warning of envReport.warnings) {
|
|
21872
|
+
logger.warn(warning);
|
|
21873
|
+
}
|
|
21874
|
+
const projectMapCacheDir = join38(baseDir, ".mma");
|
|
21478
21875
|
const indexerModule = new IndexerModule({
|
|
21479
21876
|
baseDir,
|
|
21480
21877
|
cacheDir: projectMapCacheDir
|
|
@@ -21485,9 +21882,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21485
21882
|
logger.warn(`Project indexing failed: ${err.message}`);
|
|
21486
21883
|
}
|
|
21487
21884
|
const skillsLoader = new SkillsLoader;
|
|
21488
|
-
const builtinDir =
|
|
21489
|
-
const globalDir =
|
|
21490
|
-
const projectSkillsDir =
|
|
21885
|
+
const builtinDir = join38(import.meta.dirname, "skills", "builtin");
|
|
21886
|
+
const globalDir = join38(homedir12(), ".agents", "skills");
|
|
21887
|
+
const projectSkillsDir = join38(baseDir, ".mma", "skills");
|
|
21491
21888
|
const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
|
|
21492
21889
|
const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
|
|
21493
21890
|
const skillsModule = new SkillsModule(availableSkills, skillsBudget);
|
|
@@ -21503,11 +21900,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21503
21900
|
essential: true,
|
|
21504
21901
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
21505
21902
|
};
|
|
21506
|
-
const agentsMdGlobal =
|
|
21507
|
-
if (!
|
|
21903
|
+
const agentsMdGlobal = join38(dir, "AGENTS.md");
|
|
21904
|
+
if (!existsSync45(agentsMdGlobal)) {
|
|
21508
21905
|
writeFileSync15(agentsMdGlobal, "", "utf-8");
|
|
21509
21906
|
}
|
|
21510
|
-
const sessionDir =
|
|
21907
|
+
const sessionDir = join38(dir, "sessions");
|
|
21511
21908
|
const sessionStore = new SessionStore(sessionDir);
|
|
21512
21909
|
sessionStore.init();
|
|
21513
21910
|
const sessionManager = new SessionManager(sessionStore, {
|
|
@@ -21584,7 +21981,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21584
21981
|
const mcpModule = new MCPModule(config);
|
|
21585
21982
|
await mcpModule.initialize();
|
|
21586
21983
|
moduleRegistry.register(mcpModule);
|
|
21587
|
-
const memoryStore = new MemoryStore(
|
|
21984
|
+
const memoryStore = new MemoryStore(join38(dir, "memory"));
|
|
21588
21985
|
const memoryModule = new MemoryModule(memoryStore);
|
|
21589
21986
|
moduleRegistry.register(memoryModule);
|
|
21590
21987
|
if (config.browser.enabled) {
|
|
@@ -21596,7 +21993,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21596
21993
|
pluginManager.register(browserPlugin);
|
|
21597
21994
|
}
|
|
21598
21995
|
}
|
|
21599
|
-
const lspModule = new LspModule(config.lsp);
|
|
21996
|
+
const lspModule = new LspModule(config.lsp, undefined, logger);
|
|
21600
21997
|
moduleRegistry.register(lspModule);
|
|
21601
21998
|
const lspPlugin = lspModule.getPlugin();
|
|
21602
21999
|
if (lspPlugin) {
|
|
@@ -21637,8 +22034,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21637
22034
|
pluginManager.register(plugin);
|
|
21638
22035
|
pluginManager.register(plugin2);
|
|
21639
22036
|
const pluginLoader = new PluginLoader;
|
|
21640
|
-
const globalPluginsDir =
|
|
21641
|
-
const projectPluginsDir =
|
|
22037
|
+
const globalPluginsDir = join38(homedir12(), ".mma", "plugins");
|
|
22038
|
+
const projectPluginsDir = join38(baseDir, ".mma", "plugins");
|
|
21642
22039
|
const mmaVersion = readMmaVersion();
|
|
21643
22040
|
pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger, {
|
|
21644
22041
|
source: "global",
|
|
@@ -21664,13 +22061,13 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21664
22061
|
const skipAgentsMd = noAgentsMd === true;
|
|
21665
22062
|
if (!skipAgentsMd) {
|
|
21666
22063
|
const agentsMdCandidates = [
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
22064
|
+
join38(baseDir, "AGENTS.md"),
|
|
22065
|
+
join38(baseDir, ".mma", "AGENTS.md"),
|
|
22066
|
+
join38(dir, "AGENTS.md")
|
|
21670
22067
|
];
|
|
21671
22068
|
for (const p of agentsMdCandidates) {
|
|
21672
|
-
if (
|
|
21673
|
-
const content =
|
|
22069
|
+
if (existsSync45(p)) {
|
|
22070
|
+
const content = readFileSync28(p, "utf-8").trim();
|
|
21674
22071
|
if (content) {
|
|
21675
22072
|
agentsMdBlocks.push({
|
|
21676
22073
|
content,
|
|
@@ -21773,6 +22170,7 @@ var init_bootstrap = __esm(() => {
|
|
|
21773
22170
|
init_i18n();
|
|
21774
22171
|
init_agent();
|
|
21775
22172
|
init_version();
|
|
22173
|
+
init_environment();
|
|
21776
22174
|
});
|
|
21777
22175
|
|
|
21778
22176
|
// node_modules/ansi-regex/index.js
|
|
@@ -22541,20 +22939,20 @@ __export(exports_manifest, {
|
|
|
22541
22939
|
getCertMark: () => getCertMark,
|
|
22542
22940
|
MANIFEST_PATH: () => MANIFEST_PATH
|
|
22543
22941
|
});
|
|
22544
|
-
import { existsSync as
|
|
22545
|
-
import { homedir as
|
|
22546
|
-
import { join as
|
|
22942
|
+
import { existsSync as existsSync46, readFileSync as readFileSync29, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
22943
|
+
import { homedir as homedir14 } from "os";
|
|
22944
|
+
import { join as join40 } from "path";
|
|
22547
22945
|
function readManifest(path = MANIFEST_PATH) {
|
|
22548
22946
|
try {
|
|
22549
|
-
if (
|
|
22550
|
-
const raw = JSON.parse(
|
|
22947
|
+
if (existsSync46(path)) {
|
|
22948
|
+
const raw = JSON.parse(readFileSync29(path, "utf-8"));
|
|
22551
22949
|
return { version: 1, certifications: raw.certifications ?? [] };
|
|
22552
22950
|
}
|
|
22553
22951
|
} catch {}
|
|
22554
22952
|
return { version: 1, certifications: [] };
|
|
22555
22953
|
}
|
|
22556
22954
|
function saveManifest(m, path = MANIFEST_PATH) {
|
|
22557
|
-
mkdirSync18(
|
|
22955
|
+
mkdirSync18(join40(homedir14(), ".mma"), { recursive: true });
|
|
22558
22956
|
writeFileSync16(path, JSON.stringify(m, null, 2), "utf-8");
|
|
22559
22957
|
}
|
|
22560
22958
|
function upsertCertification(entry, path = MANIFEST_PATH) {
|
|
@@ -22589,7 +22987,7 @@ function getCertMark(model, providerUrl, currentVersion, path = MANIFEST_PATH) {
|
|
|
22589
22987
|
}
|
|
22590
22988
|
var MANIFEST_PATH;
|
|
22591
22989
|
var init_manifest = __esm(() => {
|
|
22592
|
-
MANIFEST_PATH =
|
|
22990
|
+
MANIFEST_PATH = join40(homedir14(), ".mma", "certifications.json");
|
|
22593
22991
|
});
|
|
22594
22992
|
|
|
22595
22993
|
// node_modules/yaml/dist/nodes/identity.js
|
|
@@ -29712,8 +30110,8 @@ var init_scenarios = __esm(() => {
|
|
|
29712
30110
|
});
|
|
29713
30111
|
|
|
29714
30112
|
// src/modules/certification/loader.ts
|
|
29715
|
-
import { existsSync as
|
|
29716
|
-
import { join as
|
|
30113
|
+
import { existsSync as existsSync47, readdirSync as readdirSync16, readFileSync as readFileSync30 } from "fs";
|
|
30114
|
+
import { join as join41 } from "path";
|
|
29717
30115
|
function validateScenario(s) {
|
|
29718
30116
|
const errors2 = [];
|
|
29719
30117
|
const isSkip = s.mode === "skip";
|
|
@@ -29762,12 +30160,12 @@ function loadScenarios(userDir) {
|
|
|
29762
30160
|
else
|
|
29763
30161
|
scenarios.push(s);
|
|
29764
30162
|
}
|
|
29765
|
-
if (userDir &&
|
|
29766
|
-
for (const file of
|
|
30163
|
+
if (userDir && existsSync47(userDir)) {
|
|
30164
|
+
for (const file of readdirSync16(userDir)) {
|
|
29767
30165
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
29768
30166
|
continue;
|
|
29769
30167
|
try {
|
|
29770
|
-
const raw =
|
|
30168
|
+
const raw = readFileSync30(join41(userDir, file), "utf-8");
|
|
29771
30169
|
const data = $parse(raw);
|
|
29772
30170
|
const parsed = normalizeScenario(data, file);
|
|
29773
30171
|
const errs = validateScenario(parsed);
|
|
@@ -29820,8 +30218,8 @@ var init_loader3 = __esm(() => {
|
|
|
29820
30218
|
});
|
|
29821
30219
|
|
|
29822
30220
|
// src/modules/certification/fact-checker.ts
|
|
29823
|
-
import { existsSync as
|
|
29824
|
-
import { join as
|
|
30221
|
+
import { existsSync as existsSync48, readFileSync as readFileSync31, statSync as statSync8 } from "fs";
|
|
30222
|
+
import { join as join42 } from "path";
|
|
29825
30223
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
29826
30224
|
const failures = [];
|
|
29827
30225
|
for (const check of checks) {
|
|
@@ -29838,16 +30236,16 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
29838
30236
|
case "outputContains":
|
|
29839
30237
|
return output.includes(check.text);
|
|
29840
30238
|
case "fileExists":
|
|
29841
|
-
return isFile(
|
|
30239
|
+
return isFile(join42(sandboxDir, check.path));
|
|
29842
30240
|
case "fileNotExists":
|
|
29843
|
-
return !
|
|
30241
|
+
return !existsSync48(join42(sandboxDir, check.path));
|
|
29844
30242
|
case "dirExists":
|
|
29845
|
-
return isDir(
|
|
30243
|
+
return isDir(join42(sandboxDir, check.path));
|
|
29846
30244
|
case "fileContent": {
|
|
29847
|
-
const abs =
|
|
30245
|
+
const abs = join42(sandboxDir, check.path);
|
|
29848
30246
|
if (!isFile(abs))
|
|
29849
30247
|
return false;
|
|
29850
|
-
const content =
|
|
30248
|
+
const content = readFileSync31(abs, "utf-8");
|
|
29851
30249
|
if (check.contains !== undefined)
|
|
29852
30250
|
return content.includes(check.contains);
|
|
29853
30251
|
if (check.equals !== undefined)
|
|
@@ -29855,10 +30253,10 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
29855
30253
|
return false;
|
|
29856
30254
|
}
|
|
29857
30255
|
case "fileRegex": {
|
|
29858
|
-
const abs =
|
|
30256
|
+
const abs = join42(sandboxDir, check.path);
|
|
29859
30257
|
if (!isFile(abs))
|
|
29860
30258
|
return false;
|
|
29861
|
-
return new RegExp(check.pattern).test(
|
|
30259
|
+
return new RegExp(check.pattern).test(readFileSync31(abs, "utf-8"));
|
|
29862
30260
|
}
|
|
29863
30261
|
default:
|
|
29864
30262
|
return false;
|
|
@@ -29866,14 +30264,14 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
29866
30264
|
}
|
|
29867
30265
|
function isFile(p) {
|
|
29868
30266
|
try {
|
|
29869
|
-
return
|
|
30267
|
+
return existsSync48(p) && statSync8(p).isFile();
|
|
29870
30268
|
} catch {
|
|
29871
30269
|
return false;
|
|
29872
30270
|
}
|
|
29873
30271
|
}
|
|
29874
30272
|
function isDir(p) {
|
|
29875
30273
|
try {
|
|
29876
|
-
return
|
|
30274
|
+
return existsSync48(p) && statSync8(p).isDirectory();
|
|
29877
30275
|
} catch {
|
|
29878
30276
|
return false;
|
|
29879
30277
|
}
|
|
@@ -29904,9 +30302,9 @@ var init_fact_checker = () => {};
|
|
|
29904
30302
|
|
|
29905
30303
|
// src/modules/certification/runner.ts
|
|
29906
30304
|
import { spawn as spawn8 } from "child_process";
|
|
29907
|
-
import { existsSync as
|
|
29908
|
-
import { platform as
|
|
29909
|
-
import { join as
|
|
30305
|
+
import { existsSync as existsSync49, mkdirSync as mkdirSync19, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
|
|
30306
|
+
import { platform as platform10 } from "os";
|
|
30307
|
+
import { join as join43, resolve as resolve24, dirname as dirname15 } from "path";
|
|
29910
30308
|
async function runScenario(scenario, opts) {
|
|
29911
30309
|
if (scenario.mode === "skip") {
|
|
29912
30310
|
return {
|
|
@@ -29925,7 +30323,7 @@ async function runScenario(scenario, opts) {
|
|
|
29925
30323
|
let passed = 0;
|
|
29926
30324
|
let firstError;
|
|
29927
30325
|
for (let i = 1;i <= reps; i++) {
|
|
29928
|
-
const sandbox =
|
|
30326
|
+
const sandbox = join43(opts.sandboxBase, `run-${scenario.id}-${i}`);
|
|
29929
30327
|
let failures = [];
|
|
29930
30328
|
let exitCode = -1;
|
|
29931
30329
|
let output = "";
|
|
@@ -29939,15 +30337,15 @@ async function runScenario(scenario, opts) {
|
|
|
29939
30337
|
sandbox,
|
|
29940
30338
|
scenario.prompt
|
|
29941
30339
|
];
|
|
29942
|
-
const
|
|
30340
|
+
const env3 = {
|
|
29943
30341
|
...process.env,
|
|
29944
30342
|
MMA_MODEL: opts.model,
|
|
29945
30343
|
MMA_PROVIDER_BASEURL: opts.providerUrl,
|
|
29946
30344
|
MMA_CONTEXT_WINDOW: String(opts.contextWindow ?? 32000)
|
|
29947
30345
|
};
|
|
29948
30346
|
if (opts.providerKey)
|
|
29949
|
-
|
|
29950
|
-
const res = await runner(
|
|
30347
|
+
env3.MMA_PROVIDER_APIKEY = opts.providerKey;
|
|
30348
|
+
const res = await runner(env3, opts.mmaRoot, args, timeoutMs);
|
|
29951
30349
|
output = `${res.stdout}
|
|
29952
30350
|
${res.stderr}`;
|
|
29953
30351
|
exitCode = res.code ?? -1;
|
|
@@ -29986,25 +30384,25 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
|
29986
30384
|
rmSync4(sandbox, { recursive: true, force: true });
|
|
29987
30385
|
mkdirSync19(sandbox, { recursive: true });
|
|
29988
30386
|
for (const f of scenario.fixtures ?? []) {
|
|
29989
|
-
const src =
|
|
29990
|
-
if (!
|
|
30387
|
+
const src = join43(mmaRoot, f.source);
|
|
30388
|
+
if (!existsSync49(src)) {
|
|
29991
30389
|
throw new Error(`fixture missing: ${f.source}`);
|
|
29992
30390
|
}
|
|
29993
|
-
const dest =
|
|
29994
|
-
mkdirSync19(
|
|
30391
|
+
const dest = join43(sandbox, f.dest);
|
|
30392
|
+
mkdirSync19(dirname15(dest), { recursive: true });
|
|
29995
30393
|
cpSync2(src, dest);
|
|
29996
30394
|
}
|
|
29997
30395
|
}
|
|
29998
30396
|
function resolveMmaEntry(mmaRoot) {
|
|
29999
|
-
const dev =
|
|
30000
|
-
if (
|
|
30397
|
+
const dev = join43(mmaRoot, "src", "cli", "main.ts");
|
|
30398
|
+
if (existsSync49(dev))
|
|
30001
30399
|
return dev;
|
|
30002
|
-
return
|
|
30400
|
+
return join43(mmaRoot, "dist", "main.js");
|
|
30003
30401
|
}
|
|
30004
30402
|
function findMmaRoot(fromDir) {
|
|
30005
30403
|
const candidates = [resolve24(fromDir, "..", "..", ".."), resolve24(fromDir, "..")];
|
|
30006
30404
|
for (const c of candidates) {
|
|
30007
|
-
if (
|
|
30405
|
+
if (existsSync49(join43(c, "package.json")))
|
|
30008
30406
|
return c;
|
|
30009
30407
|
}
|
|
30010
30408
|
return process.cwd();
|
|
@@ -30013,7 +30411,7 @@ function killTree2(child) {
|
|
|
30013
30411
|
const pid = child.pid;
|
|
30014
30412
|
if (!pid)
|
|
30015
30413
|
return;
|
|
30016
|
-
if (
|
|
30414
|
+
if (platform10() === "win32") {
|
|
30017
30415
|
spawn8("taskkill", ["/pid", String(pid), "/T", "/F"], {
|
|
30018
30416
|
windowsHide: true,
|
|
30019
30417
|
stdio: "ignore"
|
|
@@ -30028,10 +30426,10 @@ function killTree2(child) {
|
|
|
30028
30426
|
} catch {}
|
|
30029
30427
|
}
|
|
30030
30428
|
}
|
|
30031
|
-
var defaultRunner2 = (
|
|
30429
|
+
var defaultRunner2 = (env3, cwd, args, timeoutMs) => new Promise((resolvePromise) => {
|
|
30032
30430
|
const child = spawn8(process.execPath, args, {
|
|
30033
30431
|
cwd,
|
|
30034
|
-
env:
|
|
30432
|
+
env: env3,
|
|
30035
30433
|
windowsHide: true,
|
|
30036
30434
|
stdio: ["ignore", "pipe", "pipe"]
|
|
30037
30435
|
});
|
|
@@ -30071,16 +30469,16 @@ __export(exports_cli, {
|
|
|
30071
30469
|
certList: () => certList
|
|
30072
30470
|
});
|
|
30073
30471
|
import { rmSync as rmSync5 } from "fs";
|
|
30074
|
-
import { homedir as
|
|
30075
|
-
import { join as
|
|
30076
|
-
import { fileURLToPath as
|
|
30077
|
-
import { existsSync as
|
|
30472
|
+
import { homedir as homedir15 } from "os";
|
|
30473
|
+
import { join as join44, dirname as dirname16 } from "path";
|
|
30474
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
30475
|
+
import { existsSync as existsSync50, readFileSync as readFileSync32 } from "fs";
|
|
30078
30476
|
function readVersion() {
|
|
30079
|
-
const candidates = [
|
|
30477
|
+
const candidates = [join44(MMA_ROOT, "package.json")];
|
|
30080
30478
|
for (const p of candidates) {
|
|
30081
|
-
if (
|
|
30479
|
+
if (existsSync50(p)) {
|
|
30082
30480
|
try {
|
|
30083
|
-
const raw = JSON.parse(
|
|
30481
|
+
const raw = JSON.parse(readFileSync32(p, "utf-8"));
|
|
30084
30482
|
if (raw.version)
|
|
30085
30483
|
return raw.version;
|
|
30086
30484
|
} catch {}
|
|
@@ -30116,7 +30514,7 @@ async function certify(opts) {
|
|
|
30116
30514
|
return;
|
|
30117
30515
|
}
|
|
30118
30516
|
console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
|
|
30119
|
-
const sandboxBase =
|
|
30517
|
+
const sandboxBase = join44(process.cwd(), ".mma", "certification");
|
|
30120
30518
|
const results = [];
|
|
30121
30519
|
const total = selected.length;
|
|
30122
30520
|
let idx = 0;
|
|
@@ -30228,9 +30626,9 @@ var init_cli = __esm(() => {
|
|
|
30228
30626
|
init_loader3();
|
|
30229
30627
|
init_runner2();
|
|
30230
30628
|
init_manifest();
|
|
30231
|
-
HERE =
|
|
30629
|
+
HERE = dirname16(fileURLToPath4(import.meta.url));
|
|
30232
30630
|
MMA_ROOT = findMmaRoot(HERE);
|
|
30233
|
-
USER_SCENARIO_DIR =
|
|
30631
|
+
USER_SCENARIO_DIR = join44(homedir15(), ".mma", "certification", "scenarios");
|
|
30234
30632
|
});
|
|
30235
30633
|
|
|
30236
30634
|
// src/cli/repl-commands.ts
|
|
@@ -30239,17 +30637,17 @@ __export(exports_repl_commands, {
|
|
|
30239
30637
|
registerAllCommands: () => registerAllCommands,
|
|
30240
30638
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
30241
30639
|
});
|
|
30242
|
-
import { join as
|
|
30243
|
-
import { homedir as
|
|
30244
|
-
import { existsSync as
|
|
30245
|
-
import { fileURLToPath as
|
|
30640
|
+
import { join as join46, dirname as dirname18 } from "path";
|
|
30641
|
+
import { homedir as homedir17 } from "os";
|
|
30642
|
+
import { existsSync as existsSync52, readFileSync as readFileSync34 } from "fs";
|
|
30643
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
30246
30644
|
function readVersion3() {
|
|
30247
|
-
const here =
|
|
30248
|
-
const candidates = [
|
|
30645
|
+
const here = dirname18(fileURLToPath6(import.meta.url));
|
|
30646
|
+
const candidates = [join46(here, "..", "..", "package.json"), join46(here, "..", "package.json")];
|
|
30249
30647
|
for (const p of candidates) {
|
|
30250
|
-
if (
|
|
30648
|
+
if (existsSync52(p)) {
|
|
30251
30649
|
try {
|
|
30252
|
-
const raw = JSON.parse(
|
|
30650
|
+
const raw = JSON.parse(readFileSync34(p, "utf8"));
|
|
30253
30651
|
if (raw.version)
|
|
30254
30652
|
return raw.version;
|
|
30255
30653
|
} catch {}
|
|
@@ -30313,7 +30711,7 @@ function registerMmaCommands(ctx) {
|
|
|
30313
30711
|
}
|
|
30314
30712
|
try {
|
|
30315
30713
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
30316
|
-
const { existsSync:
|
|
30714
|
+
const { existsSync: existsSync53 } = await import("fs");
|
|
30317
30715
|
const { resolve: resolve25 } = await import("path");
|
|
30318
30716
|
let dataUrl;
|
|
30319
30717
|
let label;
|
|
@@ -30333,7 +30731,7 @@ function registerMmaCommands(ctx) {
|
|
|
30333
30731
|
label = source;
|
|
30334
30732
|
} else {
|
|
30335
30733
|
const absPath = resolve25(process.cwd(), source);
|
|
30336
|
-
if (!
|
|
30734
|
+
if (!existsSync53(absPath)) {
|
|
30337
30735
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
30338
30736
|
return;
|
|
30339
30737
|
}
|
|
@@ -30412,7 +30810,7 @@ function registerMmaCommands(ctx) {
|
|
|
30412
30810
|
console.log(pc2.yellow(t("repl.wizard_running")));
|
|
30413
30811
|
await ctx.withExclusiveInput(async () => {
|
|
30414
30812
|
const answers = await runSetup(ctx.rl);
|
|
30415
|
-
const configPath =
|
|
30813
|
+
const configPath = join46(homedir17(), ".mma", "config.json");
|
|
30416
30814
|
ctx.config.provider.type = answers.provider;
|
|
30417
30815
|
ctx.config.provider.baseUrl = answers.apiBase;
|
|
30418
30816
|
ctx.config.provider.apiKey = answers.apiKey;
|
|
@@ -30466,7 +30864,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
30466
30864
|
return;
|
|
30467
30865
|
}
|
|
30468
30866
|
ctx.config.provider.type = name;
|
|
30469
|
-
const configPath =
|
|
30867
|
+
const configPath = join46(homedir17(), ".mma", "config.json");
|
|
30470
30868
|
saveConfig(ctx.config, configPath);
|
|
30471
30869
|
await ctx.agent.reconfigure(ctx.config);
|
|
30472
30870
|
console.log(pc2.green(t("repl.provider_set", { name })));
|
|
@@ -30522,7 +30920,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
30522
30920
|
return;
|
|
30523
30921
|
}
|
|
30524
30922
|
ctx.config.model = name;
|
|
30525
|
-
const configPath =
|
|
30923
|
+
const configPath = join46(homedir17(), ".mma", "config.json");
|
|
30526
30924
|
saveConfig(ctx.config, configPath);
|
|
30527
30925
|
await ctx.agent.reconfigure(ctx.config);
|
|
30528
30926
|
console.log(pc2.green(t("repl.model_set", { name })));
|
|
@@ -30547,7 +30945,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
30547
30945
|
return;
|
|
30548
30946
|
}
|
|
30549
30947
|
ctx.config.contextWindow = size;
|
|
30550
|
-
const configPath =
|
|
30948
|
+
const configPath = join46(homedir17(), ".mma", "config.json");
|
|
30551
30949
|
saveConfig(ctx.config, configPath);
|
|
30552
30950
|
await ctx.agent.reconfigure(ctx.config);
|
|
30553
30951
|
console.log(pc2.green(t("cli.context_set", { size })));
|
|
@@ -30565,11 +30963,11 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
30565
30963
|
}
|
|
30566
30964
|
ctx.agent.shutdown();
|
|
30567
30965
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
30568
|
-
const { homedir:
|
|
30569
|
-
const { join:
|
|
30966
|
+
const { homedir: homedir18 } = await import("os");
|
|
30967
|
+
const { join: join47 } = await import("path");
|
|
30570
30968
|
const configDir = ctx.configDir;
|
|
30571
30969
|
const baseDir = ctx.baseDir;
|
|
30572
|
-
const projectConfigPath =
|
|
30970
|
+
const projectConfigPath = join47(baseDir, ".mmrc");
|
|
30573
30971
|
const freshConfig = loadConfig2({ configDir, projectConfigPath });
|
|
30574
30972
|
Object.assign(ctx.config, freshConfig);
|
|
30575
30973
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -30620,6 +31018,70 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
30620
31018
|
}
|
|
30621
31019
|
}
|
|
30622
31020
|
});
|
|
31021
|
+
ctx.registerCommand({
|
|
31022
|
+
name: "lsp",
|
|
31023
|
+
description: t("repl.lsp"),
|
|
31024
|
+
usage: t("repl.lsp_usage"),
|
|
31025
|
+
action: async (args) => {
|
|
31026
|
+
const subcommand = args[0] || "status";
|
|
31027
|
+
const lspModule = ctx.agent.deps?.moduleRegistry?.getModules?.()?.find((m) => m.name === "lsp");
|
|
31028
|
+
if (!lspModule) {
|
|
31029
|
+
console.log(pc2.yellow(t("repl.lsp_not_available")));
|
|
31030
|
+
return;
|
|
31031
|
+
}
|
|
31032
|
+
switch (subcommand) {
|
|
31033
|
+
case "status": {
|
|
31034
|
+
const disabled = lspModule.getDisabledServers();
|
|
31035
|
+
const failures = lspModule.getFailureCounts();
|
|
31036
|
+
const config = ctx.config.lsp;
|
|
31037
|
+
console.log(pc2.bold(t("repl.lsp_status_header")));
|
|
31038
|
+
console.log(`${t("repl.lsp_enabled")} ${config?.enabled ? pc2.green("yes") : pc2.red("no")}`);
|
|
31039
|
+
if (disabled.length > 0) {
|
|
31040
|
+
console.log(pc2.yellow(`${t("repl.lsp_disabled_servers")} ${disabled.join(", ")}`));
|
|
31041
|
+
}
|
|
31042
|
+
if (failures.size > 0) {
|
|
31043
|
+
console.log(pc2.dim(t("repl.lsp_failure_counts")));
|
|
31044
|
+
for (const [server, count] of failures) {
|
|
31045
|
+
console.log(pc2.dim(` ${server}: ${count}`));
|
|
31046
|
+
}
|
|
31047
|
+
}
|
|
31048
|
+
if (disabled.length === 0 && failures.size === 0) {
|
|
31049
|
+
console.log(pc2.green(t("repl.lsp_all_ok")));
|
|
31050
|
+
}
|
|
31051
|
+
break;
|
|
31052
|
+
}
|
|
31053
|
+
case "restart": {
|
|
31054
|
+
console.log(pc2.yellow(t("repl.lsp_restarting")));
|
|
31055
|
+
lspModule.resetDisabledServers();
|
|
31056
|
+
console.log(pc2.green(t("repl.lsp_restarted")));
|
|
31057
|
+
break;
|
|
31058
|
+
}
|
|
31059
|
+
case "check": {
|
|
31060
|
+
const path = args[1];
|
|
31061
|
+
if (!path) {
|
|
31062
|
+
console.log(pc2.yellow(t("repl.lsp_check_usage")));
|
|
31063
|
+
return;
|
|
31064
|
+
}
|
|
31065
|
+
console.log(pc2.dim(t("repl.lsp_checking", { path })));
|
|
31066
|
+
try {
|
|
31067
|
+
const result = await ctx.agent.deps?.toolExecutor?.execute("lsp_check", { path }, ctx.agent.deps?.toolCtx);
|
|
31068
|
+
if (result?.output) {
|
|
31069
|
+
console.log(result.output);
|
|
31070
|
+
}
|
|
31071
|
+
} catch (e) {
|
|
31072
|
+
console.log(pc2.red(t("repl.lsp_check_error", {
|
|
31073
|
+
error: e instanceof Error ? e.message : String(e)
|
|
31074
|
+
})));
|
|
31075
|
+
}
|
|
31076
|
+
break;
|
|
31077
|
+
}
|
|
31078
|
+
default: {
|
|
31079
|
+
console.log(pc2.dim(t("repl.lsp_usage")));
|
|
31080
|
+
break;
|
|
31081
|
+
}
|
|
31082
|
+
}
|
|
31083
|
+
}
|
|
31084
|
+
});
|
|
30623
31085
|
}
|
|
30624
31086
|
function registerSessionCommands(ctx) {
|
|
30625
31087
|
if (!ctx.sessionManager)
|
|
@@ -30874,6 +31336,7 @@ var init_repl_commands = __esm(() => {
|
|
|
30874
31336
|
reload: "agent",
|
|
30875
31337
|
wizard: "agent",
|
|
30876
31338
|
sysprompt: "agent",
|
|
31339
|
+
lsp: "agent",
|
|
30877
31340
|
sessions: "session",
|
|
30878
31341
|
new: "session",
|
|
30879
31342
|
resume: "session",
|
|
@@ -30905,15 +31368,15 @@ init_bootstrap();
|
|
|
30905
31368
|
init_config2();
|
|
30906
31369
|
init_setup();
|
|
30907
31370
|
init_i18n();
|
|
30908
|
-
import { join as
|
|
30909
|
-
import { homedir as
|
|
30910
|
-
import { existsSync as
|
|
31371
|
+
import { join as join45, dirname as dirname17 } from "path";
|
|
31372
|
+
import { homedir as homedir16 } from "os";
|
|
31373
|
+
import { existsSync as existsSync51, readFileSync as readFileSync33 } from "fs";
|
|
30911
31374
|
|
|
30912
31375
|
// src/cli/security-commands.ts
|
|
30913
31376
|
init_bootstrap();
|
|
30914
31377
|
init_config2();
|
|
30915
|
-
import { join as
|
|
30916
|
-
import { homedir as
|
|
31378
|
+
import { join as join39 } from "path";
|
|
31379
|
+
import { homedir as homedir13 } from "os";
|
|
30917
31380
|
|
|
30918
31381
|
// src/modules/security/security-policies.ts
|
|
30919
31382
|
init_security();
|
|
@@ -31426,7 +31889,7 @@ function createSecurityCommand(program2) {
|
|
|
31426
31889
|
}
|
|
31427
31890
|
});
|
|
31428
31891
|
securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
|
|
31429
|
-
const configPath =
|
|
31892
|
+
const configPath = join39(homedir13(), ".mma", "config.json");
|
|
31430
31893
|
const { config: appConfig } = await bootstrap();
|
|
31431
31894
|
const validPresets = ["strict", "balanced", "permissive"];
|
|
31432
31895
|
if (!validPresets.includes(preset)) {
|
|
@@ -31441,7 +31904,7 @@ function createSecurityCommand(program2) {
|
|
|
31441
31904
|
console.log(t("cli.security.policy_description", { description: policy.description }));
|
|
31442
31905
|
});
|
|
31443
31906
|
securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
|
|
31444
|
-
const configPath =
|
|
31907
|
+
const configPath = join39(homedir13(), ".mma", "config.json");
|
|
31445
31908
|
const { config: appConfig } = await bootstrap();
|
|
31446
31909
|
appConfig.security = appConfig.security || {};
|
|
31447
31910
|
appConfig.security.sessionEncryption = {
|
|
@@ -31453,7 +31916,7 @@ function createSecurityCommand(program2) {
|
|
|
31453
31916
|
console.log(t("cli.security.encryption_enabled"));
|
|
31454
31917
|
});
|
|
31455
31918
|
securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
|
|
31456
|
-
const configPath =
|
|
31919
|
+
const configPath = join39(homedir13(), ".mma", "config.json");
|
|
31457
31920
|
const { config: appConfig } = await bootstrap();
|
|
31458
31921
|
appConfig.security = appConfig.security || {};
|
|
31459
31922
|
appConfig.security.sessionEncryption = {
|
|
@@ -31465,7 +31928,7 @@ function createSecurityCommand(program2) {
|
|
|
31465
31928
|
console.log(t("cli.security.encryption_disabled"));
|
|
31466
31929
|
});
|
|
31467
31930
|
securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
|
|
31468
|
-
const configPath =
|
|
31931
|
+
const configPath = join39(homedir13(), ".mma", "config.json");
|
|
31469
31932
|
const { config: appConfig } = await bootstrap();
|
|
31470
31933
|
appConfig.security = appConfig.security || {};
|
|
31471
31934
|
appConfig.security.auditNotifier = {
|
|
@@ -31479,7 +31942,7 @@ function createSecurityCommand(program2) {
|
|
|
31479
31942
|
console.log(t("cli.security.audit_enabled"));
|
|
31480
31943
|
});
|
|
31481
31944
|
securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
|
|
31482
|
-
const configPath =
|
|
31945
|
+
const configPath = join39(homedir13(), ".mma", "config.json");
|
|
31483
31946
|
const { config: appConfig } = await bootstrap();
|
|
31484
31947
|
appConfig.security = appConfig.security || {};
|
|
31485
31948
|
appConfig.security.auditNotifier = {
|
|
@@ -31543,14 +32006,14 @@ function createPluginCommand(program2) {
|
|
|
31543
32006
|
|
|
31544
32007
|
// src/cli/commands.ts
|
|
31545
32008
|
init_setup();
|
|
31546
|
-
import { fileURLToPath as
|
|
32009
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
31547
32010
|
function readVersion2() {
|
|
31548
|
-
const here =
|
|
31549
|
-
const candidates = [
|
|
32011
|
+
const here = dirname17(fileURLToPath5(import.meta.url));
|
|
32012
|
+
const candidates = [join45(here, "..", "..", "package.json"), join45(here, "..", "package.json")];
|
|
31550
32013
|
for (const p of candidates) {
|
|
31551
|
-
if (
|
|
32014
|
+
if (existsSync51(p)) {
|
|
31552
32015
|
try {
|
|
31553
|
-
const raw = JSON.parse(
|
|
32016
|
+
const raw = JSON.parse(readFileSync33(p, "utf8"));
|
|
31554
32017
|
if (raw.version)
|
|
31555
32018
|
return raw.version;
|
|
31556
32019
|
} catch {}
|
|
@@ -31563,7 +32026,7 @@ function createProgram() {
|
|
|
31563
32026
|
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"));
|
|
31564
32027
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
31565
32028
|
const answers = await runSetup();
|
|
31566
|
-
const configPath =
|
|
32029
|
+
const configPath = join45(homedir16(), ".mma", "config.json");
|
|
31567
32030
|
const { config } = await bootstrap();
|
|
31568
32031
|
config.provider.type = answers.provider;
|
|
31569
32032
|
config.provider.baseUrl = answers.apiBase;
|
|
@@ -31608,7 +32071,7 @@ function createProgram() {
|
|
|
31608
32071
|
});
|
|
31609
32072
|
const configCmd = program2.command("config").description(t("cli.manage_config"));
|
|
31610
32073
|
configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
|
|
31611
|
-
const configPath =
|
|
32074
|
+
const configPath = join45(homedir16(), ".mma", "config.json");
|
|
31612
32075
|
const { config } = await bootstrap();
|
|
31613
32076
|
const keys = key.split(".");
|
|
31614
32077
|
let obj = config;
|
|
@@ -31671,7 +32134,7 @@ function createProgram() {
|
|
|
31671
32134
|
console.log(t("cli.model_hint"));
|
|
31672
32135
|
});
|
|
31673
32136
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
31674
|
-
const configPath =
|
|
32137
|
+
const configPath = join45(homedir16(), ".mma", "config.json");
|
|
31675
32138
|
const { config } = await bootstrap();
|
|
31676
32139
|
config.model = name;
|
|
31677
32140
|
saveConfig(config, configPath);
|
|
@@ -31707,7 +32170,7 @@ function createProgram() {
|
|
|
31707
32170
|
await uncertify2(name, config);
|
|
31708
32171
|
});
|
|
31709
32172
|
program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
|
|
31710
|
-
const configPath =
|
|
32173
|
+
const configPath = join45(homedir16(), ".mma", "config.json");
|
|
31711
32174
|
const { config } = await bootstrap();
|
|
31712
32175
|
const contextWindow = parseInt(size, 10);
|
|
31713
32176
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
@@ -31725,7 +32188,7 @@ function createProgram() {
|
|
|
31725
32188
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
31726
32189
|
});
|
|
31727
32190
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
31728
|
-
const configPath =
|
|
32191
|
+
const configPath = join45(homedir16(), ".mma", "config.json");
|
|
31729
32192
|
const { config } = await bootstrap();
|
|
31730
32193
|
config.provider.type = name;
|
|
31731
32194
|
const baseUrl = HOSTED_BASE_URLS[name];
|
|
@@ -32540,9 +33003,9 @@ class LineEditor {
|
|
|
32540
33003
|
}
|
|
32541
33004
|
|
|
32542
33005
|
// src/cli/repl.ts
|
|
32543
|
-
import { existsSync as
|
|
32544
|
-
import { join as
|
|
32545
|
-
import { homedir as
|
|
33006
|
+
import { existsSync as existsSync54, readFileSync as readFileSync36, writeFileSync as writeFileSync17 } from "fs";
|
|
33007
|
+
import { join as join48 } from "path";
|
|
33008
|
+
import { homedir as homedir18 } from "os";
|
|
32546
33009
|
|
|
32547
33010
|
// src/cli/completer.ts
|
|
32548
33011
|
class SlashCommandProvider {
|
|
@@ -33113,16 +33576,24 @@ async function probeLspServers(config, baseDir, deps = {}) {
|
|
|
33113
33576
|
await probeClient.probe(server, projectRoot, serverTimeout);
|
|
33114
33577
|
ok.push({ language, ok: true, durationMs: Date.now() - started });
|
|
33115
33578
|
} catch (e) {
|
|
33579
|
+
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
33580
|
+
deps.logger?.warn(`LSP probe failed for ${language}: ${errorMsg}`, {
|
|
33581
|
+
command: server.command,
|
|
33582
|
+
timeout: serverTimeout,
|
|
33583
|
+
durationMs: Date.now() - started
|
|
33584
|
+
});
|
|
33116
33585
|
failed.push({
|
|
33117
33586
|
language,
|
|
33118
33587
|
ok: false,
|
|
33119
|
-
error:
|
|
33588
|
+
error: errorMsg,
|
|
33120
33589
|
durationMs: Date.now() - started
|
|
33121
33590
|
});
|
|
33122
33591
|
}
|
|
33123
33592
|
};
|
|
33124
33593
|
for (let i = 0;i < servers.length; i += maxParallel) {
|
|
33125
33594
|
if (Date.now() >= deadline) {
|
|
33595
|
+
const remaining = servers.slice(i).map((s) => s.language);
|
|
33596
|
+
deps.logger?.warn(`LSP probe deadline reached, skipping: ${remaining.join(", ")}`);
|
|
33126
33597
|
for (const { language } of servers.slice(i)) {
|
|
33127
33598
|
failed.push({ language, ok: false, error: "timeout", durationMs: 0 });
|
|
33128
33599
|
}
|
|
@@ -33141,14 +33612,14 @@ init_config();
|
|
|
33141
33612
|
init_colors();
|
|
33142
33613
|
init_js_identifiers();
|
|
33143
33614
|
init_i18n();
|
|
33144
|
-
import { existsSync as
|
|
33145
|
-
import { join as
|
|
33615
|
+
import { existsSync as existsSync53, readFileSync as readFileSync35 } from "fs";
|
|
33616
|
+
import { join as join47 } from "path";
|
|
33146
33617
|
function readActivePlan(baseDir) {
|
|
33147
|
-
const p =
|
|
33148
|
-
if (!
|
|
33618
|
+
const p = join47(baseDir, ".mma", "plans", "active.json");
|
|
33619
|
+
if (!existsSync53(p))
|
|
33149
33620
|
return null;
|
|
33150
33621
|
try {
|
|
33151
|
-
const raw =
|
|
33622
|
+
const raw = readFileSync35(p, "utf-8");
|
|
33152
33623
|
if (!raw.trim())
|
|
33153
33624
|
return null;
|
|
33154
33625
|
const parsed = JSON.parse(raw);
|
|
@@ -33291,10 +33762,10 @@ class Repl {
|
|
|
33291
33762
|
this.skillsModule = skillsModule;
|
|
33292
33763
|
this.pluginManager = pluginManager;
|
|
33293
33764
|
this.logger = logger;
|
|
33294
|
-
this.configDir = configDir ||
|
|
33765
|
+
this.configDir = configDir || join48(homedir18(), ".mma");
|
|
33295
33766
|
this.baseDir = baseDir || process.cwd();
|
|
33296
33767
|
this.noAgentsMd = noAgentsMd === true;
|
|
33297
|
-
this.historyPath =
|
|
33768
|
+
this.historyPath = join48(homedir18(), ".mma", "repl-history");
|
|
33298
33769
|
this.loadHistory();
|
|
33299
33770
|
this.rl = process.stdin.isTTY ? new LineEditor({
|
|
33300
33771
|
input: process.stdin,
|
|
@@ -33327,9 +33798,9 @@ class Repl {
|
|
|
33327
33798
|
this.setupListeners();
|
|
33328
33799
|
}
|
|
33329
33800
|
loadHistory() {
|
|
33330
|
-
if (
|
|
33801
|
+
if (existsSync54(this.historyPath)) {
|
|
33331
33802
|
try {
|
|
33332
|
-
const raw =
|
|
33803
|
+
const raw = readFileSync36(this.historyPath, "utf-8");
|
|
33333
33804
|
this.history = raw.split(`
|
|
33334
33805
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
33335
33806
|
} catch {
|
|
@@ -33421,6 +33892,7 @@ class Repl {
|
|
|
33421
33892
|
this.running = false;
|
|
33422
33893
|
this.saveHistory();
|
|
33423
33894
|
this.agent.shutdown();
|
|
33895
|
+
this.logger?.closeSessionLog();
|
|
33424
33896
|
if (this.exitOnClose)
|
|
33425
33897
|
process.exit(0);
|
|
33426
33898
|
});
|
|
@@ -33429,6 +33901,7 @@ class Repl {
|
|
|
33429
33901
|
this.running = false;
|
|
33430
33902
|
this.saveHistory();
|
|
33431
33903
|
this.agent.shutdown();
|
|
33904
|
+
this.logger?.closeSessionLog();
|
|
33432
33905
|
process.exit(0);
|
|
33433
33906
|
});
|
|
33434
33907
|
}
|
|
@@ -33705,11 +34178,11 @@ ${t("image.clipboard_empty")}`));
|
|
|
33705
34178
|
row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
|
|
33706
34179
|
} else {
|
|
33707
34180
|
const agentsMdCandidates = [
|
|
33708
|
-
|
|
33709
|
-
|
|
33710
|
-
|
|
34181
|
+
join48(this.baseDir, "AGENTS.md"),
|
|
34182
|
+
join48(this.baseDir, ".mma", "AGENTS.md"),
|
|
34183
|
+
join48(this.configDir, "AGENTS.md")
|
|
33711
34184
|
];
|
|
33712
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
34185
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync54(p));
|
|
33713
34186
|
if (foundAgents.length > 0) {
|
|
33714
34187
|
for (const p of foundAgents) {
|
|
33715
34188
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -33720,7 +34193,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
33720
34193
|
}
|
|
33721
34194
|
const meta = this.sessionManager?.getActiveMeta();
|
|
33722
34195
|
if (meta) {
|
|
33723
|
-
const sessionPath =
|
|
34196
|
+
const sessionPath = join48(this.configDir, "sessions", meta.id);
|
|
33724
34197
|
row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
|
|
33725
34198
|
}
|
|
33726
34199
|
const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
|
|
@@ -33775,6 +34248,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
33775
34248
|
this.running = false;
|
|
33776
34249
|
this.saveHistory();
|
|
33777
34250
|
this.agent.shutdown();
|
|
34251
|
+
this.logger?.closeSessionLog();
|
|
33778
34252
|
this.rl.close();
|
|
33779
34253
|
}
|
|
33780
34254
|
}
|
|
@@ -33805,10 +34279,10 @@ init_setup();
|
|
|
33805
34279
|
init_config2();
|
|
33806
34280
|
init_i18n();
|
|
33807
34281
|
init_colors();
|
|
33808
|
-
import { existsSync as
|
|
33809
|
-
import { join as
|
|
33810
|
-
import { homedir as
|
|
33811
|
-
import { fileURLToPath as
|
|
34282
|
+
import { existsSync as existsSync55, readFileSync as readFileSync37 } from "fs";
|
|
34283
|
+
import { join as join50, dirname as dirname19 } from "path";
|
|
34284
|
+
import { homedir as homedir20 } from "os";
|
|
34285
|
+
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
33812
34286
|
|
|
33813
34287
|
// src/modules/updater/index.ts
|
|
33814
34288
|
init_checker();
|
|
@@ -33907,14 +34381,61 @@ class UpdaterModule {
|
|
|
33907
34381
|
await this.runOnce();
|
|
33908
34382
|
}
|
|
33909
34383
|
}
|
|
34384
|
+
// src/core/crash-handler.ts
|
|
34385
|
+
init_environment();
|
|
34386
|
+
init_data_sanitizer();
|
|
34387
|
+
init_i18n();
|
|
34388
|
+
import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync20 } from "fs";
|
|
34389
|
+
import { join as join49 } from "path";
|
|
34390
|
+
import { homedir as homedir19 } from "os";
|
|
34391
|
+
var CRASH_LOG_DIR = join49(homedir19(), ".mma", "logs");
|
|
34392
|
+
var CRASH_LOG_FILE = "crash.jsonl";
|
|
34393
|
+
function formatCrashEntry(type2, err) {
|
|
34394
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
34395
|
+
const stack = err instanceof Error && err.stack ? err.stack : message;
|
|
34396
|
+
return {
|
|
34397
|
+
ts: new Date().toISOString(),
|
|
34398
|
+
type: type2,
|
|
34399
|
+
message: sanitizeLogMessage(message),
|
|
34400
|
+
stack: sanitizeLogMessage(stack),
|
|
34401
|
+
environment: collectEnvironment({ configDir: homedir19(), scanTools: false })
|
|
34402
|
+
};
|
|
34403
|
+
}
|
|
34404
|
+
function writeCrashEntry(dir, entry) {
|
|
34405
|
+
try {
|
|
34406
|
+
mkdirSync20(dir, { recursive: true });
|
|
34407
|
+
appendFileSync7(join49(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
|
|
34408
|
+
`, "utf-8");
|
|
34409
|
+
} catch {}
|
|
34410
|
+
}
|
|
34411
|
+
var installed = false;
|
|
34412
|
+
function installCrashHandlers() {
|
|
34413
|
+
if (installed)
|
|
34414
|
+
return;
|
|
34415
|
+
installed = true;
|
|
34416
|
+
process.on("uncaughtException", (err) => {
|
|
34417
|
+
const entry = formatCrashEntry("uncaughtException", err);
|
|
34418
|
+
writeCrashEntry(CRASH_LOG_DIR, entry);
|
|
34419
|
+
process.stderr.write(`${t("env.crash_stderr", { type: entry.type, message: entry.message })}
|
|
34420
|
+
`);
|
|
34421
|
+
process.exit(1);
|
|
34422
|
+
});
|
|
34423
|
+
process.on("unhandledRejection", (reason) => {
|
|
34424
|
+
const entry = formatCrashEntry("unhandledRejection", reason);
|
|
34425
|
+
writeCrashEntry(CRASH_LOG_DIR, entry);
|
|
34426
|
+
process.stderr.write(`${t("env.crash_stderr", { type: entry.type, message: entry.message })}
|
|
34427
|
+
`);
|
|
34428
|
+
});
|
|
34429
|
+
}
|
|
34430
|
+
|
|
33910
34431
|
// src/cli/main.ts
|
|
33911
34432
|
function readVersion4() {
|
|
33912
|
-
const here =
|
|
33913
|
-
const candidates = [
|
|
34433
|
+
const here = dirname19(fileURLToPath7(import.meta.url));
|
|
34434
|
+
const candidates = [join50(here, "..", "..", "package.json"), join50(here, "..", "package.json")];
|
|
33914
34435
|
for (const p of candidates) {
|
|
33915
|
-
if (
|
|
34436
|
+
if (existsSync55(p)) {
|
|
33916
34437
|
try {
|
|
33917
|
-
const raw = JSON.parse(
|
|
34438
|
+
const raw = JSON.parse(readFileSync37(p, "utf8"));
|
|
33918
34439
|
if (raw.version)
|
|
33919
34440
|
return raw.version;
|
|
33920
34441
|
} catch {}
|
|
@@ -33939,6 +34460,7 @@ function startAutoUpdate(config) {
|
|
|
33939
34460
|
}
|
|
33940
34461
|
}
|
|
33941
34462
|
async function main() {
|
|
34463
|
+
installCrashHandlers();
|
|
33942
34464
|
const program2 = createProgram();
|
|
33943
34465
|
program2.parse(process.argv);
|
|
33944
34466
|
const cmdNames = new Set(program2.commands.map((c) => c.name()));
|
|
@@ -33998,15 +34520,15 @@ async function main() {
|
|
|
33998
34520
|
await updater?.waitForIdle();
|
|
33999
34521
|
process.exit(exitCode);
|
|
34000
34522
|
} else {
|
|
34001
|
-
const configPath =
|
|
34002
|
-
if (!
|
|
34523
|
+
const configPath = join50(homedir20(), ".mma", "config.json");
|
|
34524
|
+
if (!existsSync55(configPath)) {
|
|
34003
34525
|
console.log(pc2.yellow(`
|
|
34004
34526
|
` + t("cli.first_run") + `
|
|
34005
34527
|
`));
|
|
34006
34528
|
const answers = await runSetup();
|
|
34007
34529
|
const config2 = loadConfig({
|
|
34008
|
-
configDir:
|
|
34009
|
-
projectConfigPath: projectDir ?
|
|
34530
|
+
configDir: join50(homedir20(), ".mma"),
|
|
34531
|
+
projectConfigPath: projectDir ? join50(projectDir, ".mmrc") : join50(process.cwd(), ".mmrc")
|
|
34010
34532
|
});
|
|
34011
34533
|
config2.provider.type = answers.provider;
|
|
34012
34534
|
config2.provider.baseUrl = answers.apiBase;
|