micro-models-agent 0.46.2 → 0.46.3
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/main.js +711 -784
- package/dist/modules/browser/bridge-server.mjs +202 -202
- package/dist/skills/builtin/git.md +36 -36
- package/dist/skills/builtin/typescript.md +35 -35
- package/package.json +48 -48
- package/dist/cli/commands.js +0 -323
- package/dist/cli/completer.js +0 -167
- package/dist/cli/index.js +0 -2
- package/dist/cli/main.js +0 -165
- package/dist/cli/plugin-commands.js +0 -36
- package/dist/cli/repl-commands.js +0 -661
- package/dist/cli/repl.js +0 -616
- package/dist/cli/run-result.js +0 -22
- package/dist/cli/security-commands.js +0 -164
- package/dist/cli/setup.js +0 -231
- package/dist/config/config.js +0 -249
- package/dist/config/defaults.js +0 -124
- package/dist/config/experts.js +0 -15
- package/dist/config/index.js +0 -3
- package/dist/config/security.js +0 -193
- package/dist/config/types.js +0 -1
- package/dist/core/agent-moe.js +0 -102
- package/dist/core/agent.js +0 -886
- package/dist/core/bootstrap.js +0 -404
- package/dist/core/index.js +0 -2
- package/dist/core/prompt-builder.js +0 -76
- package/dist/core/session-logger.js +0 -197
- package/dist/core/types.js +0 -1
- package/dist/core/version.js +0 -24
- package/dist/core/workspace.js +0 -76
- package/dist/i18n/en.json +0 -598
- package/dist/i18n/index.js +0 -46
- package/dist/i18n/ru.json +0 -598
- package/dist/index.js +0 -22
- package/dist/llm/image-utils.js +0 -143
- package/dist/llm/index.js +0 -4
- package/dist/llm/model-loader.js +0 -78
- package/dist/llm/openai-compat.js +0 -359
- package/dist/llm/orchestrator.js +0 -198
- package/dist/llm/provider.js +0 -10
- package/dist/llm/response.js +0 -39
- package/dist/llm/token-counter.js +0 -39
- package/dist/llm/types.js +0 -1
- package/dist/logger/app-logger.js +0 -143
- package/dist/logger/file-log.js +0 -151
- package/dist/logger/index.js +0 -1
- package/dist/migration/backup.js +0 -45
- package/dist/migration/detect.js +0 -50
- package/dist/migration/index.js +0 -2
- package/dist/modules/artifacts/store.js +0 -61
- package/dist/modules/browser/actions.js +0 -76
- package/dist/modules/browser/bridge-client.js +0 -199
- package/dist/modules/browser/bridge-path.js +0 -10
- package/dist/modules/browser/cookie-store.js +0 -24
- package/dist/modules/browser/driver.js +0 -136
- package/dist/modules/browser/index.js +0 -7
- package/dist/modules/browser/module.js +0 -29
- package/dist/modules/browser/session.js +0 -338
- package/dist/modules/browser/snapshot.js +0 -148
- package/dist/modules/browser/types.js +0 -12
- package/dist/modules/certification/cli.js +0 -174
- package/dist/modules/certification/fact-checker.js +0 -82
- package/dist/modules/certification/loader.js +0 -105
- package/dist/modules/certification/manifest.js +0 -50
- package/dist/modules/certification/runner.js +0 -159
- package/dist/modules/certification/scenarios.js +0 -124
- package/dist/modules/certification/types.js +0 -1
- package/dist/modules/context/chunk-query.js +0 -100
- package/dist/modules/context/fact-extractor.js +0 -162
- package/dist/modules/context/history.js +0 -15
- package/dist/modules/context/index.js +0 -1
- package/dist/modules/context/manager.js +0 -423
- package/dist/modules/execution/audit-runners.js +0 -152
- package/dist/modules/execution/auditor.js +0 -218
- package/dist/modules/execution/execution-plugin.js +0 -272
- package/dist/modules/execution/index.js +0 -8
- package/dist/modules/execution/module.js +0 -436
- package/dist/modules/execution/moe-executor.js +0 -291
- package/dist/modules/execution/plan-coverage.js +0 -68
- package/dist/modules/execution/plan-persister.js +0 -46
- package/dist/modules/execution/plan-store.js +0 -157
- package/dist/modules/execution/plan-tool.js +0 -508
- package/dist/modules/execution/plan-validator.js +0 -153
- package/dist/modules/execution/planner.js +0 -90
- package/dist/modules/execution/stuck-detector.js +0 -510
- package/dist/modules/execution/tracker.js +0 -67
- package/dist/modules/execution/types.js +0 -1
- package/dist/modules/execution/verifier.js +0 -222
- package/dist/modules/execution/windows-commands.js +0 -41
- package/dist/modules/hallucination/confidence.js +0 -66
- package/dist/modules/hallucination/consistency.js +0 -26
- package/dist/modules/hallucination/detector.js +0 -43
- package/dist/modules/hallucination/factual.js +0 -129
- package/dist/modules/hallucination/index.js +0 -5
- package/dist/modules/hallucination/js-identifiers.js +0 -262
- package/dist/modules/hallucination/llm-judge.js +0 -101
- package/dist/modules/index.js +0 -5
- package/dist/modules/indexer/cache.js +0 -40
- package/dist/modules/indexer/index.js +0 -3
- package/dist/modules/indexer/module.js +0 -245
- package/dist/modules/indexer/project-profile.js +0 -183
- package/dist/modules/indexer/walker.js +0 -101
- package/dist/modules/lsp/check-tool.js +0 -58
- package/dist/modules/lsp/client.js +0 -278
- package/dist/modules/lsp/command.js +0 -60
- package/dist/modules/lsp/config.js +0 -135
- package/dist/modules/lsp/index.js +0 -3
- package/dist/modules/lsp/module.js +0 -232
- package/dist/modules/lsp/probe.js +0 -76
- package/dist/modules/lsp/project-root.js +0 -32
- package/dist/modules/lsp/startup-check.js +0 -141
- package/dist/modules/lsp/types.js +0 -1
- package/dist/modules/mcp/client.js +0 -399
- package/dist/modules/mcp/index.js +0 -3
- package/dist/modules/mcp/module.js +0 -142
- package/dist/modules/mcp/registry.js +0 -15
- package/dist/modules/memory/index.js +0 -1
- package/dist/modules/memory/module.js +0 -96
- package/dist/modules/memory/search.js +0 -42
- package/dist/modules/memory/store.js +0 -69
- package/dist/modules/pipelines/engine.js +0 -60
- package/dist/modules/pipelines/index.js +0 -3
- package/dist/modules/pipelines/parser.js +0 -56
- package/dist/modules/pipelines/template.js +0 -14
- package/dist/modules/plugins/builtin/lint-on-write.js +0 -231
- package/dist/modules/plugins/builtin/notify.js +0 -9
- package/dist/modules/plugins/index.js +0 -1
- package/dist/modules/plugins/loader.js +0 -70
- package/dist/modules/plugins/manager.js +0 -217
- package/dist/modules/plugins/types.js +0 -1
- package/dist/modules/processes/detect.js +0 -34
- package/dist/modules/processes/index.js +0 -2
- package/dist/modules/processes/registry.js +0 -327
- package/dist/modules/processes/runner.js +0 -23
- package/dist/modules/registry.js +0 -47
- package/dist/modules/security/audit-log.js +0 -136
- package/dist/modules/security/audit-notifier.js +0 -292
- package/dist/modules/security/command-validator.js +0 -205
- package/dist/modules/security/content-scanner.js +0 -53
- package/dist/modules/security/data-sanitizer.js +0 -89
- package/dist/modules/security/encryption.js +0 -242
- package/dist/modules/security/index.js +0 -14
- package/dist/modules/security/network-validator.js +0 -71
- package/dist/modules/security/path-validator.js +0 -207
- package/dist/modules/security/rate-limiter.js +0 -119
- package/dist/modules/security/security-policies.js +0 -531
- package/dist/modules/security/session-encryption.js +0 -210
- package/dist/modules/security/session-isolation.js +0 -95
- package/dist/modules/session/index.js +0 -3
- package/dist/modules/session/manager.js +0 -172
- package/dist/modules/session/module.js +0 -24
- package/dist/modules/session/store.js +0 -222
- package/dist/modules/session/types.js +0 -1
- package/dist/modules/skills/index.js +0 -2
- package/dist/modules/skills/loader.js +0 -72
- package/dist/modules/skills/matcher.js +0 -27
- package/dist/modules/skills/module.js +0 -129
- package/dist/modules/types.js +0 -1
- package/dist/modules/updater/checker.js +0 -96
- package/dist/modules/updater/index.js +0 -2
- package/dist/modules/updater/module.js +0 -116
- package/dist/modules/user-profile/compressor.js +0 -16
- package/dist/modules/user-profile/index.js +0 -1
- package/dist/modules/user-profile/profile.js +0 -68
- package/dist/tools/approve.js +0 -32
- package/dist/tools/attach-image.js +0 -89
- package/dist/tools/bash.js +0 -496
- package/dist/tools/browser.js +0 -114
- package/dist/tools/chunk-query.js +0 -99
- package/dist/tools/create-dir.js +0 -55
- package/dist/tools/delete-file.js +0 -62
- package/dist/tools/download-file.js +0 -116
- package/dist/tools/edit-file.js +0 -79
- package/dist/tools/enable-tools.js +0 -58
- package/dist/tools/executor.js +0 -144
- package/dist/tools/file-info.js +0 -46
- package/dist/tools/filter-tools.js +0 -17
- package/dist/tools/glob-tool.js +0 -26
- package/dist/tools/grep-tool.js +0 -84
- package/dist/tools/hidden-tools-block.js +0 -37
- package/dist/tools/index.js +0 -78
- package/dist/tools/list-dir.js +0 -48
- package/dist/tools/load-skill.js +0 -42
- package/dist/tools/mcp-call.js +0 -68
- package/dist/tools/move-file.js +0 -85
- package/dist/tools/path-utils.js +0 -51
- package/dist/tools/pipeline-run.js +0 -144
- package/dist/tools/preview.js +0 -2
- package/dist/tools/process-kill.js +0 -29
- package/dist/tools/process-list.js +0 -36
- package/dist/tools/process-log.js +0 -45
- package/dist/tools/question.js +0 -140
- package/dist/tools/read-file.js +0 -91
- package/dist/tools/recall.js +0 -117
- package/dist/tools/registry.js +0 -47
- package/dist/tools/remember.js +0 -67
- package/dist/tools/scope-check.js +0 -30
- package/dist/tools/search-history.js +0 -84
- package/dist/tools/subagent.js +0 -196
- package/dist/tools/types.js +0 -1
- package/dist/tools/user-input.js +0 -123
- package/dist/tools/web-browse.js +0 -86
- package/dist/tools/web-fetch.js +0 -98
- package/dist/tools/web-search.js +0 -78
- package/dist/tools/write-file.js +0 -81
- package/dist/ui/box.js +0 -77
- package/dist/ui/colors.js +0 -4
- package/dist/ui/diff.js +0 -178
- package/dist/ui/index.js +0 -6
- package/dist/ui/line-editor.js +0 -703
- package/dist/ui/line-math.js +0 -69
- package/dist/ui/md-formatter.js +0 -212
- package/dist/ui/output.js +0 -13
- package/dist/ui/plan-view.js +0 -103
- package/dist/ui/renderer.js +0 -209
- package/dist/ui/spinner.js +0 -70
- package/dist/ui/table.js +0 -144
package/dist/main.js
CHANGED
|
@@ -2263,9 +2263,7 @@ var init_defaults = __esm(() => {
|
|
|
2263
2263
|
retry: {
|
|
2264
2264
|
maxRetries: 3,
|
|
2265
2265
|
baseDelay: 1000,
|
|
2266
|
-
maxDelay: 30000
|
|
2267
|
-
maxStreamRetries: 2,
|
|
2268
|
-
noDataTimeoutMs: 60000
|
|
2266
|
+
maxDelay: 30000
|
|
2269
2267
|
},
|
|
2270
2268
|
maxToolIterations: 1000,
|
|
2271
2269
|
stuckThreshold: 6,
|
|
@@ -2398,14 +2396,6 @@ Use read_file on {path} to see the current content before editing — the target
|
|
|
2398
2396
|
"error.llm_retries": "LLM request failed after retries",
|
|
2399
2397
|
"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}",
|
|
2400
2398
|
"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",
|
|
2409
2399
|
"session.started": "Session started: {id}",
|
|
2410
2400
|
"session.ended": "Session ended: {id}",
|
|
2411
2401
|
"session.not_found": "Session not found: {id}",
|
|
@@ -2789,19 +2779,6 @@ Available commands:`,
|
|
|
2789
2779
|
"repl.lsp_timeout": "timeout",
|
|
2790
2780
|
"repl.lsp_failed": "did not start",
|
|
2791
2781
|
"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}",
|
|
2805
2782
|
"repl.work_dir": "Dir:",
|
|
2806
2783
|
"repl.agents_label": "Instructions:",
|
|
2807
2784
|
"repl.not_found": "not found",
|
|
@@ -3029,6 +3006,10 @@ Apply a matching solution from these results. If none is relevant — do NOT rep
|
|
|
3029
3006
|
"tools.hidden_header": "Additional tools (enable on demand via enable_tools or route to subagent tool_tags):",
|
|
3030
3007
|
"tool.friendly.enable_tools": "Enable tools",
|
|
3031
3008
|
"cli.provider_base_hint": "Base URL set to: {baseUrl}",
|
|
3009
|
+
"cli.add_provider": "Add a provider to the config",
|
|
3010
|
+
"cli.provider_no_url": 'No base URL for provider "{name}". Pass --url.',
|
|
3011
|
+
"cli.provider_added": "Provider added: {name}",
|
|
3012
|
+
"cli.provider_switch_hint": "Switch to it with: mma provider use <name>",
|
|
3032
3013
|
"repl.cost": "Total cost: {cost}",
|
|
3033
3014
|
"repl.tokens": "Tokens used: {tokens}"
|
|
3034
3015
|
};
|
|
@@ -3082,14 +3063,6 @@ var init_ru = __esm(() => {
|
|
|
3082
3063
|
"error.llm_retries": "Запрос LLM не удался после повторов",
|
|
3083
3064
|
"error.llm_429": "Превышен лимит запросов (HTTP 429) для {model} на {baseUrl}. Провайдер ограничивает трафик — особенно строгие free-модели. Получите API-ключ или переключитесь на платную/быструю модель: {baseUrl}",
|
|
3084
3065
|
"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",
|
|
3093
3066
|
"session.started": "Сессия начата: {id}",
|
|
3094
3067
|
"session.ended": "Сессия завершена: {id}",
|
|
3095
3068
|
"session.not_found": "Сессия не найдена: {id}",
|
|
@@ -3468,19 +3441,6 @@ var init_ru = __esm(() => {
|
|
|
3468
3441
|
"repl.lsp_timeout": "таймаут",
|
|
3469
3442
|
"repl.lsp_failed": "не стартовал",
|
|
3470
3443
|
"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}",
|
|
3484
3444
|
"repl.work_dir": "Директория:",
|
|
3485
3445
|
"repl.agents_label": "Инструкции:",
|
|
3486
3446
|
"repl.not_found": "не найден",
|
|
@@ -3714,6 +3674,10 @@ var init_ru = __esm(() => {
|
|
|
3714
3674
|
"tools.hidden_header": "Дополнительные тулы (включите по требованию через enable_tools или маршрутизируйте через subagent tool_tags):",
|
|
3715
3675
|
"tool.friendly.enable_tools": "Включить тулы",
|
|
3716
3676
|
"cli.provider_base_hint": "Базовый URL установлен: {baseUrl}",
|
|
3677
|
+
"cli.add_provider": "Добавить провайдера в конфиг",
|
|
3678
|
+
"cli.provider_no_url": 'Нет базового URL для провайдера "{name}". Укажите --url.',
|
|
3679
|
+
"cli.provider_added": "Провайдер добавлен: {name}",
|
|
3680
|
+
"cli.provider_switch_hint": "Переключитесь на него: mma provider use <имя>",
|
|
3717
3681
|
"repl.cost": "Итого потрачено: {cost}",
|
|
3718
3682
|
"repl.tokens": "Потрачено токенов: {tokens}"
|
|
3719
3683
|
};
|
|
@@ -4640,20 +4604,6 @@ class Logger {
|
|
|
4640
4604
|
}
|
|
4641
4605
|
return sanitized;
|
|
4642
4606
|
}
|
|
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
|
-
}
|
|
4657
4607
|
}
|
|
4658
4608
|
var import_picocolors, LEVELS, LEVEL_COLORS;
|
|
4659
4609
|
var init_app_logger = __esm(() => {
|
|
@@ -4669,6 +4619,26 @@ var init_app_logger = __esm(() => {
|
|
|
4669
4619
|
};
|
|
4670
4620
|
});
|
|
4671
4621
|
|
|
4622
|
+
// src/modules/providers/registry.ts
|
|
4623
|
+
class ProviderRegistry {
|
|
4624
|
+
specs = new Map;
|
|
4625
|
+
register(spec) {
|
|
4626
|
+
this.specs.set(spec.type, spec);
|
|
4627
|
+
}
|
|
4628
|
+
get(type) {
|
|
4629
|
+
return this.specs.get(type);
|
|
4630
|
+
}
|
|
4631
|
+
has(type) {
|
|
4632
|
+
return this.specs.has(type);
|
|
4633
|
+
}
|
|
4634
|
+
list() {
|
|
4635
|
+
return [...this.specs.values()];
|
|
4636
|
+
}
|
|
4637
|
+
types() {
|
|
4638
|
+
return [...this.specs.keys()];
|
|
4639
|
+
}
|
|
4640
|
+
}
|
|
4641
|
+
|
|
4672
4642
|
// node_modules/base64-js/index.js
|
|
4673
4643
|
var require_base64_js = __commonJS((exports) => {
|
|
4674
4644
|
exports.byteLength = byteLength;
|
|
@@ -5230,9 +5200,7 @@ class OpenAICompatProvider {
|
|
|
5230
5200
|
this.retryConfig = config.retry ?? {
|
|
5231
5201
|
maxRetries: 3,
|
|
5232
5202
|
baseDelay: 1000,
|
|
5233
|
-
maxDelay: 30000
|
|
5234
|
-
maxStreamRetries: 2,
|
|
5235
|
-
noDataTimeoutMs: 60000
|
|
5203
|
+
maxDelay: 30000
|
|
5236
5204
|
};
|
|
5237
5205
|
this.rateLimiter = createRateLimiter(config.rateLimits);
|
|
5238
5206
|
}
|
|
@@ -5263,32 +5231,6 @@ class OpenAICompatProvider {
|
|
|
5263
5231
|
}
|
|
5264
5232
|
}
|
|
5265
5233
|
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) {
|
|
5292
5234
|
const body = buildRequestBody({
|
|
5293
5235
|
model: this.model,
|
|
5294
5236
|
messages,
|
|
@@ -5304,11 +5246,8 @@ class OpenAICompatProvider {
|
|
|
5304
5246
|
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
5305
5247
|
}
|
|
5306
5248
|
const controller = new AbortController;
|
|
5307
|
-
|
|
5308
|
-
const timeoutId = setTimeout(() =>
|
|
5309
|
-
timedOut = true;
|
|
5310
|
-
controller.abort();
|
|
5311
|
-
}, REQUEST_TIMEOUT_MS);
|
|
5249
|
+
const totalTimeoutMs = 120000;
|
|
5250
|
+
const timeoutId = setTimeout(() => controller.abort(), totalTimeoutMs);
|
|
5312
5251
|
const abortSignal = (() => {
|
|
5313
5252
|
if (!signal)
|
|
5314
5253
|
return controller.signal;
|
|
@@ -5321,31 +5260,20 @@ class OpenAICompatProvider {
|
|
|
5321
5260
|
return controller.signal;
|
|
5322
5261
|
}
|
|
5323
5262
|
})();
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
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
|
-
}
|
|
5263
|
+
const response = await this.fetchWithRetry(`${this.config.baseUrl}/chat/completions`, {
|
|
5264
|
+
method: "POST",
|
|
5265
|
+
headers,
|
|
5266
|
+
body: JSON.stringify(body),
|
|
5267
|
+
signal: abortSignal
|
|
5268
|
+
});
|
|
5339
5269
|
if (!response.ok) {
|
|
5340
5270
|
clearTimeout(timeoutId);
|
|
5341
5271
|
const errorText = await response.text();
|
|
5342
|
-
|
|
5272
|
+
throw new Error(t("error.llm_api", {
|
|
5343
5273
|
status: response.status,
|
|
5344
5274
|
statusText: response.statusText,
|
|
5345
5275
|
errorText
|
|
5346
5276
|
}));
|
|
5347
|
-
err.llmTerminal = true;
|
|
5348
|
-
throw err;
|
|
5349
5277
|
}
|
|
5350
5278
|
const reader = response.body?.getReader();
|
|
5351
5279
|
if (!reader) {
|
|
@@ -5356,29 +5284,9 @@ class OpenAICompatProvider {
|
|
|
5356
5284
|
let buffer = "";
|
|
5357
5285
|
const toolCallAccs = new Map;
|
|
5358
5286
|
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
|
-
});
|
|
5379
5287
|
try {
|
|
5380
5288
|
while (true) {
|
|
5381
|
-
const { done, value } = await
|
|
5289
|
+
const { done, value } = await reader.read();
|
|
5382
5290
|
if (done)
|
|
5383
5291
|
break;
|
|
5384
5292
|
buffer += decoder.decode(value, { stream: true });
|
|
@@ -5390,10 +5298,8 @@ class OpenAICompatProvider {
|
|
|
5390
5298
|
if (!trimmed || !trimmed.startsWith("data: "))
|
|
5391
5299
|
continue;
|
|
5392
5300
|
const data = trimmed.slice(6);
|
|
5393
|
-
if (data === "[DONE]")
|
|
5394
|
-
sawDone = true;
|
|
5301
|
+
if (data === "[DONE]")
|
|
5395
5302
|
continue;
|
|
5396
|
-
}
|
|
5397
5303
|
try {
|
|
5398
5304
|
const parsed = JSON.parse(data);
|
|
5399
5305
|
const choice = parsed.choices?.[0];
|
|
@@ -5410,7 +5316,6 @@ class OpenAICompatProvider {
|
|
|
5410
5316
|
const delta = choice.delta || {};
|
|
5411
5317
|
const finishReason = choice.finish_reason;
|
|
5412
5318
|
if (delta.reasoning_content) {
|
|
5413
|
-
onEmit();
|
|
5414
5319
|
yield { type: "reasoning", content: delta.reasoning_content };
|
|
5415
5320
|
}
|
|
5416
5321
|
if (delta.tool_calls) {
|
|
@@ -5430,13 +5335,11 @@ class OpenAICompatProvider {
|
|
|
5430
5335
|
}
|
|
5431
5336
|
}
|
|
5432
5337
|
if (delta.content) {
|
|
5433
|
-
onEmit();
|
|
5434
5338
|
yield { type: "text", content: delta.content };
|
|
5435
5339
|
}
|
|
5436
5340
|
if (finishReason === "tool_calls" && toolCallAccs.size > 0) {
|
|
5437
5341
|
for (const [, acc] of toolCallAccs) {
|
|
5438
5342
|
if (acc.name) {
|
|
5439
|
-
onEmit();
|
|
5440
5343
|
yield {
|
|
5441
5344
|
type: "tool_call",
|
|
5442
5345
|
toolCall: {
|
|
@@ -5453,14 +5356,12 @@ class OpenAICompatProvider {
|
|
|
5453
5356
|
}
|
|
5454
5357
|
}
|
|
5455
5358
|
if (usage) {
|
|
5456
|
-
onEmit();
|
|
5457
5359
|
yield { type: "done", usage };
|
|
5458
5360
|
}
|
|
5459
5361
|
} finally {
|
|
5460
5362
|
clearTimeout(timeoutId);
|
|
5461
5363
|
reader.releaseLock();
|
|
5462
5364
|
}
|
|
5463
|
-
return sawDone;
|
|
5464
5365
|
}
|
|
5465
5366
|
async doNonStreaming(messages, tools, signal, options) {
|
|
5466
5367
|
const body = buildRequestBody({
|
|
@@ -5477,30 +5378,12 @@ class OpenAICompatProvider {
|
|
|
5477
5378
|
if (this.config.apiKey && this.config.apiKey !== "not-needed") {
|
|
5478
5379
|
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
5479
5380
|
}
|
|
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
|
-
})();
|
|
5498
5381
|
try {
|
|
5499
5382
|
const response = await this.fetchWithRetry(`${this.config.baseUrl}/chat/completions`, {
|
|
5500
5383
|
method: "POST",
|
|
5501
5384
|
headers,
|
|
5502
5385
|
body: JSON.stringify(body),
|
|
5503
|
-
signal
|
|
5386
|
+
signal
|
|
5504
5387
|
});
|
|
5505
5388
|
if (!response.ok) {
|
|
5506
5389
|
const errorText = await response.text();
|
|
@@ -5547,12 +5430,7 @@ class OpenAICompatProvider {
|
|
|
5547
5430
|
}
|
|
5548
5431
|
return chunks;
|
|
5549
5432
|
} catch (err) {
|
|
5550
|
-
if (timedOut && err?.name === "AbortError") {
|
|
5551
|
-
throw new Error(t("error.llm_timeout", { timeout: REQUEST_TIMEOUT_MS }));
|
|
5552
|
-
}
|
|
5553
5433
|
throw err instanceof Error ? err : new Error(String(err));
|
|
5554
|
-
} finally {
|
|
5555
|
-
clearTimeout(timeoutId);
|
|
5556
5434
|
}
|
|
5557
5435
|
}
|
|
5558
5436
|
countTokens(text) {
|
|
@@ -5636,13 +5514,281 @@ class OpenAICompatProvider {
|
|
|
5636
5514
|
});
|
|
5637
5515
|
}
|
|
5638
5516
|
}
|
|
5639
|
-
var REQUEST_TIMEOUT_MS = 120000;
|
|
5640
5517
|
var init_openai_compat = __esm(() => {
|
|
5641
5518
|
init_token_counter();
|
|
5642
5519
|
init_i18n();
|
|
5643
5520
|
init_rate_limiter();
|
|
5644
5521
|
});
|
|
5645
5522
|
|
|
5523
|
+
// src/modules/providers/presets.ts
|
|
5524
|
+
function openaiCompat(opts) {
|
|
5525
|
+
const retry = opts.retry ?? {
|
|
5526
|
+
maxRetries: 3,
|
|
5527
|
+
baseDelay: 1000,
|
|
5528
|
+
maxDelay: 30000
|
|
5529
|
+
};
|
|
5530
|
+
const rateLimits = opts.rateLimits;
|
|
5531
|
+
return new OpenAICompatProvider({
|
|
5532
|
+
model: opts.model,
|
|
5533
|
+
baseUrl: opts.baseUrl,
|
|
5534
|
+
apiKey: opts.apiKey,
|
|
5535
|
+
contextWindow: opts.contextWindow,
|
|
5536
|
+
retry,
|
|
5537
|
+
rateLimits
|
|
5538
|
+
});
|
|
5539
|
+
}
|
|
5540
|
+
var OPENAI_COMPAT, OPENROUTER, OPENAI, ANTHROPIC, OPENCODE_ZEN, OPENCODE_GO, BUILTIN_PROVIDERS, HOSTED_BASE_URLS;
|
|
5541
|
+
var init_presets = __esm(() => {
|
|
5542
|
+
init_openai_compat();
|
|
5543
|
+
OPENAI_COMPAT = {
|
|
5544
|
+
type: "openai-compat",
|
|
5545
|
+
label: "OpenAI-compatible (LM Studio, Ollama, vLLM, etc.)",
|
|
5546
|
+
baseUrl: "",
|
|
5547
|
+
capabilities: {
|
|
5548
|
+
streaming: true,
|
|
5549
|
+
tools: true,
|
|
5550
|
+
vision: false,
|
|
5551
|
+
reasoningEffort: false,
|
|
5552
|
+
listModels: true,
|
|
5553
|
+
requiresKey: false,
|
|
5554
|
+
auth: "bearer"
|
|
5555
|
+
},
|
|
5556
|
+
create: openaiCompat
|
|
5557
|
+
};
|
|
5558
|
+
OPENROUTER = {
|
|
5559
|
+
type: "openrouter",
|
|
5560
|
+
label: "OpenRouter (openrouter.ai)",
|
|
5561
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
5562
|
+
capabilities: {
|
|
5563
|
+
streaming: true,
|
|
5564
|
+
tools: true,
|
|
5565
|
+
vision: true,
|
|
5566
|
+
reasoningEffort: false,
|
|
5567
|
+
listModels: true,
|
|
5568
|
+
requiresKey: true,
|
|
5569
|
+
auth: "bearer"
|
|
5570
|
+
},
|
|
5571
|
+
create: openaiCompat
|
|
5572
|
+
};
|
|
5573
|
+
OPENAI = {
|
|
5574
|
+
type: "openai",
|
|
5575
|
+
label: "OpenAI API",
|
|
5576
|
+
baseUrl: "https://api.openai.com/v1",
|
|
5577
|
+
capabilities: {
|
|
5578
|
+
streaming: true,
|
|
5579
|
+
tools: true,
|
|
5580
|
+
vision: true,
|
|
5581
|
+
reasoningEffort: true,
|
|
5582
|
+
listModels: true,
|
|
5583
|
+
requiresKey: true,
|
|
5584
|
+
auth: "bearer"
|
|
5585
|
+
},
|
|
5586
|
+
create: openaiCompat
|
|
5587
|
+
};
|
|
5588
|
+
ANTHROPIC = {
|
|
5589
|
+
type: "anthropic",
|
|
5590
|
+
label: "Anthropic Claude",
|
|
5591
|
+
baseUrl: "https://api.anthropic.com",
|
|
5592
|
+
capabilities: {
|
|
5593
|
+
streaming: false,
|
|
5594
|
+
tools: false,
|
|
5595
|
+
vision: true,
|
|
5596
|
+
reasoningEffort: false,
|
|
5597
|
+
listModels: false,
|
|
5598
|
+
requiresKey: true,
|
|
5599
|
+
auth: "header"
|
|
5600
|
+
},
|
|
5601
|
+
create: openaiCompat
|
|
5602
|
+
};
|
|
5603
|
+
OPENCODE_ZEN = {
|
|
5604
|
+
type: "opencode-zen",
|
|
5605
|
+
label: "OpenCode Zen (opencode.ai/zen)",
|
|
5606
|
+
baseUrl: "https://opencode.ai/zen/v1",
|
|
5607
|
+
capabilities: {
|
|
5608
|
+
streaming: true,
|
|
5609
|
+
tools: true,
|
|
5610
|
+
vision: false,
|
|
5611
|
+
reasoningEffort: false,
|
|
5612
|
+
listModels: true,
|
|
5613
|
+
requiresKey: false,
|
|
5614
|
+
auth: "bearer"
|
|
5615
|
+
},
|
|
5616
|
+
create: openaiCompat
|
|
5617
|
+
};
|
|
5618
|
+
OPENCODE_GO = {
|
|
5619
|
+
type: "opencode-go",
|
|
5620
|
+
label: "OpenCode Go (opencode.ai/go)",
|
|
5621
|
+
baseUrl: "https://opencode.ai/zen/go/v1",
|
|
5622
|
+
capabilities: {
|
|
5623
|
+
streaming: true,
|
|
5624
|
+
tools: true,
|
|
5625
|
+
vision: false,
|
|
5626
|
+
reasoningEffort: false,
|
|
5627
|
+
listModels: true,
|
|
5628
|
+
requiresKey: false,
|
|
5629
|
+
auth: "bearer"
|
|
5630
|
+
},
|
|
5631
|
+
create: openaiCompat
|
|
5632
|
+
};
|
|
5633
|
+
BUILTIN_PROVIDERS = [
|
|
5634
|
+
OPENAI_COMPAT,
|
|
5635
|
+
OPENROUTER,
|
|
5636
|
+
OPENAI,
|
|
5637
|
+
ANTHROPIC,
|
|
5638
|
+
OPENCODE_ZEN,
|
|
5639
|
+
OPENCODE_GO
|
|
5640
|
+
];
|
|
5641
|
+
HOSTED_BASE_URLS = {};
|
|
5642
|
+
for (const spec of BUILTIN_PROVIDERS) {
|
|
5643
|
+
if (spec.baseUrl)
|
|
5644
|
+
HOSTED_BASE_URLS[spec.type] = spec.baseUrl;
|
|
5645
|
+
}
|
|
5646
|
+
});
|
|
5647
|
+
|
|
5648
|
+
// src/modules/providers/create.ts
|
|
5649
|
+
var exports_create = {};
|
|
5650
|
+
__export(exports_create, {
|
|
5651
|
+
defaultRegistry: () => defaultRegistry,
|
|
5652
|
+
createProvider: () => createProvider
|
|
5653
|
+
});
|
|
5654
|
+
function createProvider(type, opts, registry = defaultRegistry()) {
|
|
5655
|
+
const spec = registry.get(type);
|
|
5656
|
+
if (!spec) {
|
|
5657
|
+
return BUILTIN_PROVIDERS[0].create(opts);
|
|
5658
|
+
}
|
|
5659
|
+
return spec.create(opts);
|
|
5660
|
+
}
|
|
5661
|
+
function defaultRegistry() {
|
|
5662
|
+
const registry = new ProviderRegistry;
|
|
5663
|
+
for (const spec of BUILTIN_PROVIDERS) {
|
|
5664
|
+
registry.register(spec);
|
|
5665
|
+
}
|
|
5666
|
+
return registry;
|
|
5667
|
+
}
|
|
5668
|
+
var init_create = __esm(() => {
|
|
5669
|
+
init_presets();
|
|
5670
|
+
});
|
|
5671
|
+
|
|
5672
|
+
// src/modules/providers/manager.ts
|
|
5673
|
+
class ProviderManager {
|
|
5674
|
+
entries;
|
|
5675
|
+
activeProviderName;
|
|
5676
|
+
model;
|
|
5677
|
+
opts;
|
|
5678
|
+
registry;
|
|
5679
|
+
cache = new Map;
|
|
5680
|
+
constructor(config, opts) {
|
|
5681
|
+
this.opts = opts;
|
|
5682
|
+
this.registry = opts.registry ?? defaultRegistry();
|
|
5683
|
+
this.entries = this.normalizeEntries(config);
|
|
5684
|
+
this.activeProviderName = this.resolveActive(config);
|
|
5685
|
+
this.model = "";
|
|
5686
|
+
}
|
|
5687
|
+
get activeModel() {
|
|
5688
|
+
return this.model;
|
|
5689
|
+
}
|
|
5690
|
+
get activeName() {
|
|
5691
|
+
return this.activeProviderName;
|
|
5692
|
+
}
|
|
5693
|
+
get active() {
|
|
5694
|
+
return this.build(this.activeProviderName);
|
|
5695
|
+
}
|
|
5696
|
+
get activeEntry() {
|
|
5697
|
+
const entry = this.entryByName(this.activeProviderName);
|
|
5698
|
+
if (!entry)
|
|
5699
|
+
throw new Error(`Unknown active provider "${this.activeProviderName}"`);
|
|
5700
|
+
return entry;
|
|
5701
|
+
}
|
|
5702
|
+
list() {
|
|
5703
|
+
return this.entries.map((e) => {
|
|
5704
|
+
const preset = this.registry.get(e.type);
|
|
5705
|
+
return { ...e, label: e.label || preset?.label || e.type };
|
|
5706
|
+
});
|
|
5707
|
+
}
|
|
5708
|
+
listNames() {
|
|
5709
|
+
return this.list().map((e) => e.label);
|
|
5710
|
+
}
|
|
5711
|
+
switch(name, model) {
|
|
5712
|
+
if (!this.entryByName(name)) {
|
|
5713
|
+
throw new Error(`Unknown provider "${name}"`);
|
|
5714
|
+
}
|
|
5715
|
+
this.activeProviderName = name;
|
|
5716
|
+
if (model !== undefined)
|
|
5717
|
+
this.model = model;
|
|
5718
|
+
return this.active;
|
|
5719
|
+
}
|
|
5720
|
+
setModel(model) {
|
|
5721
|
+
this.model = model;
|
|
5722
|
+
return this.active;
|
|
5723
|
+
}
|
|
5724
|
+
toConfig() {
|
|
5725
|
+
const active = this.activeEntry;
|
|
5726
|
+
return {
|
|
5727
|
+
active: this.activeProviderName,
|
|
5728
|
+
entries: this.entries,
|
|
5729
|
+
fallback: false,
|
|
5730
|
+
type: active.type,
|
|
5731
|
+
baseUrl: active.baseUrl,
|
|
5732
|
+
apiKey: active.apiKey
|
|
5733
|
+
};
|
|
5734
|
+
}
|
|
5735
|
+
normalizeEntries(config) {
|
|
5736
|
+
if (Array.isArray(config.entries) && config.entries.length > 0) {
|
|
5737
|
+
return config.entries.map((e) => ({ ...e, label: e.label || e.type }));
|
|
5738
|
+
}
|
|
5739
|
+
return [
|
|
5740
|
+
{
|
|
5741
|
+
type: config.type ?? "openai-compat",
|
|
5742
|
+
label: config.type ?? "openai-compat",
|
|
5743
|
+
baseUrl: config.baseUrl ?? "",
|
|
5744
|
+
apiKey: config.apiKey
|
|
5745
|
+
}
|
|
5746
|
+
];
|
|
5747
|
+
}
|
|
5748
|
+
resolveActive(config) {
|
|
5749
|
+
if (config.active && this.entryByName(config.active))
|
|
5750
|
+
return config.active;
|
|
5751
|
+
const first = this.entries[0];
|
|
5752
|
+
return first ? first.label ?? "openai-compat" : "openai-compat";
|
|
5753
|
+
}
|
|
5754
|
+
entryByName(name) {
|
|
5755
|
+
return this.entries.find((e) => e.label === name || e.type === name);
|
|
5756
|
+
}
|
|
5757
|
+
build(name) {
|
|
5758
|
+
const entry = this.entryByName(name);
|
|
5759
|
+
if (!entry)
|
|
5760
|
+
throw new Error(`Unknown provider "${name}"`);
|
|
5761
|
+
const key = `${name}|${this.model}`;
|
|
5762
|
+
const cached = this.cache.get(key);
|
|
5763
|
+
if (cached)
|
|
5764
|
+
return cached;
|
|
5765
|
+
const provider = createProvider(entry.type, {
|
|
5766
|
+
model: this.model,
|
|
5767
|
+
baseUrl: entry.baseUrl,
|
|
5768
|
+
apiKey: entry.apiKey,
|
|
5769
|
+
contextWindow: entry.contextWindow ?? this.opts.contextWindow,
|
|
5770
|
+
retry: entry.retry ?? this.opts.retry,
|
|
5771
|
+
rateLimits: entry.rateLimits ?? this.opts.rateLimits
|
|
5772
|
+
}, this.registry);
|
|
5773
|
+
this.cache.set(key, provider);
|
|
5774
|
+
return provider;
|
|
5775
|
+
}
|
|
5776
|
+
resetCache() {
|
|
5777
|
+
this.cache.clear();
|
|
5778
|
+
}
|
|
5779
|
+
}
|
|
5780
|
+
var init_manager = __esm(() => {
|
|
5781
|
+
init_create();
|
|
5782
|
+
init_presets();
|
|
5783
|
+
});
|
|
5784
|
+
|
|
5785
|
+
// src/modules/providers/index.ts
|
|
5786
|
+
var init_providers = __esm(() => {
|
|
5787
|
+
init_create();
|
|
5788
|
+
init_manager();
|
|
5789
|
+
init_presets();
|
|
5790
|
+
});
|
|
5791
|
+
|
|
5646
5792
|
// src/llm/model-loader.ts
|
|
5647
5793
|
class ModelLoader {
|
|
5648
5794
|
baseUrl;
|
|
@@ -6414,10 +6560,20 @@ var init_audit_log = __esm(() => {
|
|
|
6414
6560
|
});
|
|
6415
6561
|
|
|
6416
6562
|
// src/tools/path-utils.ts
|
|
6417
|
-
import { resolve as resolve3, normalize as normalize2, dirname as dirname3, basename, sep } from "path";
|
|
6563
|
+
import { resolve as resolve3, normalize as normalize2, dirname as dirname3, basename, sep, isAbsolute } from "path";
|
|
6418
6564
|
import { existsSync as existsSync9 } from "fs";
|
|
6419
6565
|
function safeResolvePath(baseDir, userPath) {
|
|
6420
6566
|
const norm = normalize2(userPath);
|
|
6567
|
+
if (isAbsolute(norm)) {
|
|
6568
|
+
if (existsSync9(norm) || existsSync9(dirname3(norm)))
|
|
6569
|
+
return norm;
|
|
6570
|
+
const stripped2 = norm.replace(/^[/\\]/, "");
|
|
6571
|
+
const relativeCandidate = resolve3(baseDir, stripped2);
|
|
6572
|
+
if (existsSync9(relativeCandidate) || existsSync9(dirname3(relativeCandidate))) {
|
|
6573
|
+
return relativeCandidate;
|
|
6574
|
+
}
|
|
6575
|
+
return norm;
|
|
6576
|
+
}
|
|
6421
6577
|
const stripped = norm.replace(/^[/\\]/, "");
|
|
6422
6578
|
const resolved = resolve3(baseDir, stripped);
|
|
6423
6579
|
if (existsSync9(resolved) || existsSync9(dirname3(resolved)))
|
|
@@ -8401,9 +8557,11 @@ var init_prompt_builder = __esm(() => {
|
|
|
8401
8557
|
// src/core/session-logger.ts
|
|
8402
8558
|
class SessionLogger {
|
|
8403
8559
|
session;
|
|
8560
|
+
getCaller;
|
|
8404
8561
|
logger;
|
|
8405
|
-
constructor(session, logger) {
|
|
8562
|
+
constructor(session, logger, getCaller) {
|
|
8406
8563
|
this.session = session;
|
|
8564
|
+
this.getCaller = getCaller;
|
|
8407
8565
|
this.logger = logger;
|
|
8408
8566
|
this.bindSessionDir();
|
|
8409
8567
|
}
|
|
@@ -8441,12 +8599,15 @@ class SessionLogger {
|
|
|
8441
8599
|
});
|
|
8442
8600
|
}
|
|
8443
8601
|
logAssistant(content, reasoning, toolCalls, iteration) {
|
|
8602
|
+
const caller = this.getCaller?.();
|
|
8444
8603
|
if (reasoning) {
|
|
8445
8604
|
this.session?.appendLog({
|
|
8446
8605
|
ts: new Date().toISOString(),
|
|
8447
8606
|
type: "reasoning",
|
|
8448
8607
|
content: reasoning,
|
|
8449
|
-
iteration
|
|
8608
|
+
iteration,
|
|
8609
|
+
provider: caller?.provider,
|
|
8610
|
+
model: caller?.model
|
|
8450
8611
|
});
|
|
8451
8612
|
}
|
|
8452
8613
|
this.session?.appendLog({
|
|
@@ -8460,14 +8621,19 @@ class SessionLogger {
|
|
|
8460
8621
|
arguments: tc.arguments
|
|
8461
8622
|
}))
|
|
8462
8623
|
} : {},
|
|
8463
|
-
iteration
|
|
8624
|
+
iteration,
|
|
8625
|
+
provider: caller?.provider,
|
|
8626
|
+
model: caller?.model
|
|
8464
8627
|
});
|
|
8465
8628
|
}
|
|
8466
8629
|
saveAssistantMessage(content) {
|
|
8630
|
+
const caller = this.getCaller?.();
|
|
8467
8631
|
this.session?.appendMessage({
|
|
8468
8632
|
role: "assistant",
|
|
8469
8633
|
content: content.slice(0, 500),
|
|
8470
|
-
timestamp: new Date().toISOString()
|
|
8634
|
+
timestamp: new Date().toISOString(),
|
|
8635
|
+
provider: caller?.provider,
|
|
8636
|
+
model: caller?.model
|
|
8471
8637
|
});
|
|
8472
8638
|
}
|
|
8473
8639
|
logToolDefs(toolCount, toolNames, iteration) {
|
|
@@ -8490,11 +8656,14 @@ class SessionLogger {
|
|
|
8490
8656
|
});
|
|
8491
8657
|
}
|
|
8492
8658
|
logToolResult(call, result, duration, iteration) {
|
|
8659
|
+
const caller = this.getCaller?.();
|
|
8493
8660
|
this.session?.appendMessage({
|
|
8494
8661
|
role: "tool",
|
|
8495
8662
|
content: result.output.slice(0, 500),
|
|
8496
8663
|
name: call.name,
|
|
8497
|
-
timestamp: new Date().toISOString()
|
|
8664
|
+
timestamp: new Date().toISOString(),
|
|
8665
|
+
provider: caller?.provider,
|
|
8666
|
+
model: caller?.model
|
|
8498
8667
|
});
|
|
8499
8668
|
this.session?.appendLog({
|
|
8500
8669
|
ts: new Date().toISOString(),
|
|
@@ -8505,7 +8674,9 @@ class SessionLogger {
|
|
|
8505
8674
|
content: result.output.slice(0, 1000),
|
|
8506
8675
|
diff: result.diff,
|
|
8507
8676
|
duration,
|
|
8508
|
-
iteration
|
|
8677
|
+
iteration,
|
|
8678
|
+
provider: caller?.provider,
|
|
8679
|
+
model: caller?.model
|
|
8509
8680
|
});
|
|
8510
8681
|
}
|
|
8511
8682
|
logCompaction(info) {
|
|
@@ -8532,6 +8703,8 @@ class SessionLogger {
|
|
|
8532
8703
|
type: "context",
|
|
8533
8704
|
content: info.kind === "start" ? "context snapshot at session start" : `context at iteration ${info.iteration}`,
|
|
8534
8705
|
iteration: info.iteration,
|
|
8706
|
+
provider: info.provider,
|
|
8707
|
+
model: info.model,
|
|
8535
8708
|
window: info.window,
|
|
8536
8709
|
systemBudget: info.systemBudget,
|
|
8537
8710
|
reserveBudget: info.reserveBudget,
|
|
@@ -8551,6 +8724,8 @@ class SessionLogger {
|
|
|
8551
8724
|
ts: new Date().toISOString(),
|
|
8552
8725
|
type: "llm_usage",
|
|
8553
8726
|
iteration,
|
|
8727
|
+
provider: usage.provider,
|
|
8728
|
+
model: usage.model,
|
|
8554
8729
|
promptTokens: usage.promptTokens,
|
|
8555
8730
|
completionTokens: usage.completionTokens,
|
|
8556
8731
|
totalTokens: usage.totalTokens,
|
|
@@ -9363,18 +9538,20 @@ class OrchestratorClient {
|
|
|
9363
9538
|
this.config = config;
|
|
9364
9539
|
if (config.model) {
|
|
9365
9540
|
if (config.provider) {
|
|
9366
|
-
this.provider =
|
|
9541
|
+
this.provider = createProvider(config.provider.type ?? "openai-compat", {
|
|
9367
9542
|
model: config.model,
|
|
9368
9543
|
baseUrl: config.provider.baseUrl || "http://localhost:1234/v1",
|
|
9369
9544
|
apiKey: config.provider.apiKey,
|
|
9545
|
+
contextWindow: 32768,
|
|
9370
9546
|
retry: config.retry
|
|
9371
9547
|
});
|
|
9372
9548
|
} else if (defaultProvider) {
|
|
9373
9549
|
this.provider = defaultProvider;
|
|
9374
9550
|
} else {
|
|
9375
|
-
this.provider =
|
|
9551
|
+
this.provider = createProvider("openai-compat", {
|
|
9376
9552
|
model: config.model,
|
|
9377
9553
|
baseUrl: "http://localhost:1234/v1",
|
|
9554
|
+
contextWindow: 32768,
|
|
9378
9555
|
retry: config.retry
|
|
9379
9556
|
});
|
|
9380
9557
|
}
|
|
@@ -9541,7 +9718,7 @@ Respond with JSON only:
|
|
|
9541
9718
|
|
|
9542
9719
|
Max 3 re-plan cycles. After 3 cycles, return partial result.`;
|
|
9543
9720
|
var init_orchestrator = __esm(() => {
|
|
9544
|
-
|
|
9721
|
+
init_create();
|
|
9545
9722
|
init_esm();
|
|
9546
9723
|
});
|
|
9547
9724
|
|
|
@@ -10239,7 +10416,7 @@ var init_stuck_detector = __esm(() => {
|
|
|
10239
10416
|
|
|
10240
10417
|
// src/modules/artifacts/store.ts
|
|
10241
10418
|
import { existsSync as existsSync18, mkdirSync as mkdirSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "node:fs";
|
|
10242
|
-
import { resolve as resolve10, relative, isAbsolute } from "node:path";
|
|
10419
|
+
import { resolve as resolve10, relative, isAbsolute as isAbsolute2 } from "node:path";
|
|
10243
10420
|
|
|
10244
10421
|
class ArtifactStore {
|
|
10245
10422
|
root;
|
|
@@ -10259,7 +10436,7 @@ class ArtifactStore {
|
|
|
10259
10436
|
const rel = relative(root, candidate);
|
|
10260
10437
|
if (rel === "")
|
|
10261
10438
|
return true;
|
|
10262
|
-
return !rel.startsWith("..") && !
|
|
10439
|
+
return !rel.startsWith("..") && !isAbsolute2(rel);
|
|
10263
10440
|
}
|
|
10264
10441
|
save(name, content, ext = "md") {
|
|
10265
10442
|
const safe = ArtifactStore.sanitizeName(name);
|
|
@@ -11606,6 +11783,8 @@ var init_pricing = __esm(() => {
|
|
|
11606
11783
|
});
|
|
11607
11784
|
|
|
11608
11785
|
// src/core/agent.ts
|
|
11786
|
+
import { join as join14 } from "path";
|
|
11787
|
+
import { homedir as homedir5 } from "os";
|
|
11609
11788
|
function isToolCallJson(text) {
|
|
11610
11789
|
const trimmed = text.trim();
|
|
11611
11790
|
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
@@ -11670,6 +11849,17 @@ class Agent {
|
|
|
11670
11849
|
blocks: result.blocks
|
|
11671
11850
|
};
|
|
11672
11851
|
}
|
|
11852
|
+
callerProvenance() {
|
|
11853
|
+
const manager = this.deps.providerManager;
|
|
11854
|
+
if (manager) {
|
|
11855
|
+
return {
|
|
11856
|
+
provider: manager.activeName,
|
|
11857
|
+
model: manager.activeModel || this.deps.config.model
|
|
11858
|
+
};
|
|
11859
|
+
}
|
|
11860
|
+
const p = this.deps.config.provider;
|
|
11861
|
+
return { provider: p.type, model: this.deps.config.model };
|
|
11862
|
+
}
|
|
11673
11863
|
logContextStat(kind, iteration, slog, blocks) {
|
|
11674
11864
|
const cm = this.deps.contextManager;
|
|
11675
11865
|
if (typeof cm.getSnapshot !== "function")
|
|
@@ -11677,9 +11867,12 @@ class Agent {
|
|
|
11677
11867
|
const snap = cm.getSnapshot();
|
|
11678
11868
|
const history = cm.getActiveHistory();
|
|
11679
11869
|
const systemMsg = history.find((m) => m.role === "system");
|
|
11870
|
+
const caller = this.callerProvenance();
|
|
11680
11871
|
slog.logContext({
|
|
11681
11872
|
kind,
|
|
11682
11873
|
iteration,
|
|
11874
|
+
provider: caller.provider,
|
|
11875
|
+
model: caller.model,
|
|
11683
11876
|
window: snap.window,
|
|
11684
11877
|
systemBudget: snap.budget.systemPrompt,
|
|
11685
11878
|
reserveBudget: snap.budget.responseReserve,
|
|
@@ -11738,7 +11931,6 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11738
11931
|
onPhase?.(phase);
|
|
11739
11932
|
}
|
|
11740
11933
|
async run(input, onChunk, onMeta, onTool, onPhase) {
|
|
11741
|
-
this.shutdownRequested = false;
|
|
11742
11934
|
this.setScope();
|
|
11743
11935
|
const {
|
|
11744
11936
|
config,
|
|
@@ -11750,7 +11942,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11750
11942
|
sessionManager,
|
|
11751
11943
|
baseDir
|
|
11752
11944
|
} = this.deps;
|
|
11753
|
-
const slog = new SessionLogger(sessionManager, logger);
|
|
11945
|
+
const slog = new SessionLogger(sessionManager, logger, () => this.callerProvenance());
|
|
11754
11946
|
if (sessionManager && !sessionManager.getActive()) {
|
|
11755
11947
|
sessionManager.create();
|
|
11756
11948
|
logger.debug(`Session started: ${sessionManager.getActive()}`);
|
|
@@ -11812,7 +12004,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11812
12004
|
sessionManager,
|
|
11813
12005
|
baseDir
|
|
11814
12006
|
} = this.deps;
|
|
11815
|
-
const slog = new SessionLogger(sessionManager, logger);
|
|
12007
|
+
const slog = new SessionLogger(sessionManager, logger, () => this.callerProvenance());
|
|
11816
12008
|
this.abortController = new AbortController;
|
|
11817
12009
|
let iteration = 0;
|
|
11818
12010
|
let lastText = "";
|
|
@@ -11915,7 +12107,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11915
12107
|
const llmStart = Date.now();
|
|
11916
12108
|
const promptBefore = apiPromptTokens;
|
|
11917
12109
|
const completionBefore = apiCompletionTokens;
|
|
11918
|
-
logger.logLLMRequest(config.model, history.length, input,
|
|
12110
|
+
logger.logLLMRequest(config.model, history.length, input, this.callerProvenance().provider);
|
|
11919
12111
|
try {
|
|
11920
12112
|
for await (const chunk of llmProvider.chat(history, allToolsForBudget, this.abortController?.signal)) {
|
|
11921
12113
|
if (this.shutdownRequested)
|
|
@@ -11977,14 +12169,17 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
11977
12169
|
this.emitPhase(iteration, "done", onPhase);
|
|
11978
12170
|
}
|
|
11979
12171
|
apiCompletionChars += (textContent || reasoningContent).length;
|
|
11980
|
-
logger.logLLMResponse(config.model, (textContent || reasoningContent).length, Date.now() - llmStart, undefined,
|
|
12172
|
+
logger.logLLMResponse(config.model, (textContent || reasoningContent).length, Date.now() - llmStart, undefined, this.callerProvenance().provider);
|
|
11981
12173
|
{
|
|
11982
12174
|
const usagePrompt = apiPromptTokens - promptBefore;
|
|
11983
12175
|
const usageCompletion = apiCompletionTokens - completionBefore;
|
|
11984
12176
|
const source = usagePrompt > 0 || usageCompletion > 0 ? "api" : "estimate";
|
|
11985
12177
|
const prompt = source === "api" ? usagePrompt : contextManager.getEstimatedTokens();
|
|
11986
12178
|
const completion = source === "api" ? usageCompletion : Math.ceil((textContent || reasoningContent).length / 4);
|
|
12179
|
+
const caller = this.callerProvenance();
|
|
11987
12180
|
slog.logLlmUsage(iteration, {
|
|
12181
|
+
provider: caller.provider,
|
|
12182
|
+
model: caller.model,
|
|
11988
12183
|
promptTokens: prompt,
|
|
11989
12184
|
completionTokens: completion,
|
|
11990
12185
|
totalTokens: prompt + completion,
|
|
@@ -12101,6 +12296,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
12101
12296
|
arguments: call.arguments
|
|
12102
12297
|
});
|
|
12103
12298
|
const tokensAfterTool = contextManager.getEstimatedTokens();
|
|
12299
|
+
const caller = this.callerProvenance();
|
|
12104
12300
|
onTool?.({
|
|
12105
12301
|
type: "end",
|
|
12106
12302
|
tool: call.name,
|
|
@@ -12108,7 +12304,9 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
12108
12304
|
duration,
|
|
12109
12305
|
error: !result.success,
|
|
12110
12306
|
ctxDelta: tokensAfterTool - tokensBeforeTool,
|
|
12111
|
-
costUsd: this.costTracker.total
|
|
12307
|
+
costUsd: this.costTracker.total,
|
|
12308
|
+
provider: caller.provider,
|
|
12309
|
+
model: caller.model
|
|
12112
12310
|
});
|
|
12113
12311
|
summaries.push(`[Tool: ${call.name} (${JSON.stringify(call.arguments)}) → ${truncatedOutput.slice(0, 200)}]`);
|
|
12114
12312
|
if (config.session.autoSave) {
|
|
@@ -12368,23 +12566,57 @@ ${warnLine}
|
|
|
12368
12566
|
this.systemPromptAdded = false;
|
|
12369
12567
|
}
|
|
12370
12568
|
async reconfigure(config) {
|
|
12371
|
-
const { OpenAICompatProvider: OpenAICompatProvider2 } = await Promise.resolve().then(() => (init_openai_compat(), exports_openai_compat));
|
|
12372
12569
|
const { TokenCounter: TokenCounter2 } = await Promise.resolve().then(() => (init_token_counter(), exports_token_counter));
|
|
12373
|
-
const
|
|
12374
|
-
|
|
12375
|
-
|
|
12570
|
+
const manager = this.deps.providerManager;
|
|
12571
|
+
const newProvider = manager ? manager.setModel(config.model) : await this.buildLegacyProvider(config, config.model);
|
|
12572
|
+
this.deps.llmProvider = newProvider;
|
|
12573
|
+
this.deps.toolExecutor.updateProvider(newProvider);
|
|
12574
|
+
this.deps.toolExecutor.ctx.llmProvider = newProvider;
|
|
12575
|
+
const newTokenCounter = new TokenCounter2(config.model);
|
|
12576
|
+
this.deps.contextManager.resize(config.contextWindow, config.contextBudget, newTokenCounter);
|
|
12577
|
+
this.deps.config = config;
|
|
12578
|
+
this.costTracker.setModel(config.model);
|
|
12579
|
+
}
|
|
12580
|
+
async buildLegacyProvider(config, model) {
|
|
12581
|
+
const { createProvider: createProvider2 } = await Promise.resolve().then(() => (init_create(), exports_create));
|
|
12582
|
+
return createProvider2(config.provider.type ?? "openai-compat", {
|
|
12583
|
+
model,
|
|
12584
|
+
baseUrl: config.provider.baseUrl ?? "",
|
|
12376
12585
|
apiKey: config.provider.apiKey,
|
|
12377
12586
|
contextWindow: config.contextWindow,
|
|
12378
12587
|
retry: config.retry,
|
|
12379
12588
|
rateLimits: config.security?.rateLimits
|
|
12380
12589
|
});
|
|
12590
|
+
}
|
|
12591
|
+
async setProvider(name, model) {
|
|
12592
|
+
const manager = this.deps.providerManager;
|
|
12593
|
+
if (!manager) {
|
|
12594
|
+
throw new Error("ProviderManager is not available (legacy single-provider config)");
|
|
12595
|
+
}
|
|
12596
|
+
const newProvider = manager.switch(name, model ?? this.deps.config.model);
|
|
12597
|
+
const config = this.deps.config;
|
|
12598
|
+
config.provider.active = name;
|
|
12599
|
+
config.provider.type = manager.activeEntry.type;
|
|
12600
|
+
config.provider.baseUrl = manager.activeEntry.baseUrl;
|
|
12601
|
+
config.provider.apiKey = manager.activeEntry.apiKey;
|
|
12381
12602
|
this.deps.llmProvider = newProvider;
|
|
12382
12603
|
this.deps.toolExecutor.updateProvider(newProvider);
|
|
12383
12604
|
this.deps.toolExecutor.ctx.llmProvider = newProvider;
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12605
|
+
this.costTracker.setModel(newProvider.model);
|
|
12606
|
+
const configPath = join14(homedir5(), ".mma", "config.json");
|
|
12607
|
+
const { saveConfig: saveConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
12608
|
+
saveConfig2(config, configPath);
|
|
12609
|
+
}
|
|
12610
|
+
listProviders() {
|
|
12611
|
+
const manager = this.deps.providerManager;
|
|
12612
|
+
if (!manager)
|
|
12613
|
+
return [];
|
|
12614
|
+
return manager.list().map((e) => ({
|
|
12615
|
+
type: e.type,
|
|
12616
|
+
label: e.label,
|
|
12617
|
+
baseUrl: e.baseUrl,
|
|
12618
|
+
active: e.label === manager.activeName
|
|
12619
|
+
}));
|
|
12388
12620
|
}
|
|
12389
12621
|
setContext(messages) {
|
|
12390
12622
|
const { contextManager } = this.deps;
|
|
@@ -12411,6 +12643,7 @@ ${warnLine}
|
|
|
12411
12643
|
if (killed > 0) {
|
|
12412
12644
|
logger.info(`Killed ${killed} background process(es) on shutdown`);
|
|
12413
12645
|
}
|
|
12646
|
+
logger.closeSessionLog();
|
|
12414
12647
|
pluginManager.runOnSessionEnd({
|
|
12415
12648
|
logger,
|
|
12416
12649
|
sessionManager: sessionManager?.getActiveMeta(),
|
|
@@ -12887,7 +13120,7 @@ ${lines.join(`
|
|
|
12887
13120
|
}
|
|
12888
13121
|
}
|
|
12889
13122
|
var COMPACTION_INTERVAL = 15, KEEP_LAST_N = 6;
|
|
12890
|
-
var
|
|
13123
|
+
var init_manager2 = __esm(() => {
|
|
12891
13124
|
init_fact_extractor();
|
|
12892
13125
|
});
|
|
12893
13126
|
|
|
@@ -12984,7 +13217,7 @@ var init_confidence = __esm(() => {
|
|
|
12984
13217
|
|
|
12985
13218
|
// src/modules/hallucination/factual.ts
|
|
12986
13219
|
import { existsSync as existsSync23, readdirSync as readdirSync7 } from "fs";
|
|
12987
|
-
import { resolve as resolve14, isAbsolute as
|
|
13220
|
+
import { resolve as resolve14, isAbsolute as isAbsolute3, join as join15 } from "path";
|
|
12988
13221
|
|
|
12989
13222
|
class FactualCheck {
|
|
12990
13223
|
baseDir;
|
|
@@ -13023,7 +13256,7 @@ class FactualCheck {
|
|
|
13023
13256
|
return { status: "pass" };
|
|
13024
13257
|
}
|
|
13025
13258
|
pathExists(fp) {
|
|
13026
|
-
if (
|
|
13259
|
+
if (isAbsolute3(fp))
|
|
13027
13260
|
return existsSync23(fp);
|
|
13028
13261
|
if (this.knownFiles.has(fp))
|
|
13029
13262
|
return true;
|
|
@@ -13078,7 +13311,7 @@ class FactualCheck {
|
|
|
13078
13311
|
for (const entry of entries) {
|
|
13079
13312
|
if (count >= FactualCheck.MAX_INDEXED_FILES)
|
|
13080
13313
|
break;
|
|
13081
|
-
const full =
|
|
13314
|
+
const full = join15(dir, entry.name);
|
|
13082
13315
|
if (entry.isDirectory()) {
|
|
13083
13316
|
if (!IGNORED_DIRS.has(entry.name)) {
|
|
13084
13317
|
count = this.scanDir(full, index, count);
|
|
@@ -13252,7 +13485,7 @@ var init_detector = __esm(() => {
|
|
|
13252
13485
|
});
|
|
13253
13486
|
|
|
13254
13487
|
// src/modules/lsp/command.ts
|
|
13255
|
-
import { delimiter, join as
|
|
13488
|
+
import { delimiter, join as join16 } from "path";
|
|
13256
13489
|
import { existsSync as existsSync24 } from "fs";
|
|
13257
13490
|
import { platform as platform3 } from "os";
|
|
13258
13491
|
function resolveSpawnCommand(command, platformName = platform3(), pathEnv = process.env.PATH ?? "") {
|
|
@@ -13264,7 +13497,7 @@ function resolveSpawnCommand(command, platformName = platform3(), pathEnv = proc
|
|
|
13264
13497
|
const dirs = pathEnv.split(delimiter).filter(Boolean);
|
|
13265
13498
|
for (const dir of dirs) {
|
|
13266
13499
|
for (const ext of WIN_EXTS) {
|
|
13267
|
-
const candidate =
|
|
13500
|
+
const candidate = join16(dir, `${command}${ext}`);
|
|
13268
13501
|
if (existsSync24(candidate))
|
|
13269
13502
|
return `${command}${ext}`;
|
|
13270
13503
|
}
|
|
@@ -13542,7 +13775,7 @@ class PluginManager {
|
|
|
13542
13775
|
return chunk;
|
|
13543
13776
|
}
|
|
13544
13777
|
}
|
|
13545
|
-
var
|
|
13778
|
+
var init_manager3 = __esm(() => {
|
|
13546
13779
|
init_checker();
|
|
13547
13780
|
});
|
|
13548
13781
|
|
|
@@ -13562,9 +13795,9 @@ Workflow rules:
|
|
|
13562
13795
|
var init_subagent = __esm(() => {
|
|
13563
13796
|
init_i18n();
|
|
13564
13797
|
init_agent();
|
|
13565
|
-
init_manager();
|
|
13566
|
-
init_detector();
|
|
13567
13798
|
init_manager2();
|
|
13799
|
+
init_detector();
|
|
13800
|
+
init_manager3();
|
|
13568
13801
|
init_audit_log();
|
|
13569
13802
|
init_session_isolation();
|
|
13570
13803
|
init_store();
|
|
@@ -14637,8 +14870,8 @@ var init_pipeline_run = __esm(() => {
|
|
|
14637
14870
|
init_engine();
|
|
14638
14871
|
init_parser();
|
|
14639
14872
|
init_agent();
|
|
14640
|
-
init_manager();
|
|
14641
14873
|
init_manager2();
|
|
14874
|
+
init_manager3();
|
|
14642
14875
|
init_detector();
|
|
14643
14876
|
init_audit_log();
|
|
14644
14877
|
init_session_isolation();
|
|
@@ -15224,8 +15457,8 @@ ${JSON.stringify(result, null, 2)}`
|
|
|
15224
15457
|
|
|
15225
15458
|
// src/tools/search-history.ts
|
|
15226
15459
|
import * as fs from "fs";
|
|
15227
|
-
import { join as
|
|
15228
|
-
import { homedir as
|
|
15460
|
+
import { join as join17 } from "path";
|
|
15461
|
+
import { homedir as homedir6 } from "os";
|
|
15229
15462
|
function searchFile(filePath, query, maxResults, results) {
|
|
15230
15463
|
if (!fs.existsSync(filePath))
|
|
15231
15464
|
return;
|
|
@@ -15269,7 +15502,7 @@ var init_search_history = __esm(() => {
|
|
|
15269
15502
|
const query = String(args.query || "").toLowerCase();
|
|
15270
15503
|
const maxResults = Number(args.maxResults) || 5;
|
|
15271
15504
|
const sessionId = args.sessionId ? String(args.sessionId) : null;
|
|
15272
|
-
const sessionDir =
|
|
15505
|
+
const sessionDir = join17(homedir6(), ".mma", "sessions");
|
|
15273
15506
|
const results = [];
|
|
15274
15507
|
try {
|
|
15275
15508
|
if (!fs.existsSync(sessionDir)) {
|
|
@@ -15284,7 +15517,7 @@ var init_search_history = __esm(() => {
|
|
|
15284
15517
|
continue;
|
|
15285
15518
|
if (sessionId && entry.name !== sessionId)
|
|
15286
15519
|
continue;
|
|
15287
|
-
const historyFile =
|
|
15520
|
+
const historyFile = join17(sessionDir, entry.name, "history.jsonl");
|
|
15288
15521
|
searchFile(historyFile, query, maxResults, results);
|
|
15289
15522
|
if (results.length >= maxResults)
|
|
15290
15523
|
break;
|
|
@@ -15312,7 +15545,7 @@ var init_search_history = __esm(() => {
|
|
|
15312
15545
|
|
|
15313
15546
|
// src/modules/memory/search.ts
|
|
15314
15547
|
import { readFileSync as readFileSync13, existsSync as existsSync26 } from "fs";
|
|
15315
|
-
import { join as
|
|
15548
|
+
import { join as join18 } from "path";
|
|
15316
15549
|
|
|
15317
15550
|
class MemorySearch {
|
|
15318
15551
|
memoryDir;
|
|
@@ -15323,7 +15556,7 @@ class MemorySearch {
|
|
|
15323
15556
|
const results = [];
|
|
15324
15557
|
const lowerQuery = query.toLowerCase();
|
|
15325
15558
|
for (const name of MEMORY_FILES) {
|
|
15326
|
-
const path =
|
|
15559
|
+
const path = join18(this.memoryDir, `${name}.md`);
|
|
15327
15560
|
if (!existsSync26(path))
|
|
15328
15561
|
continue;
|
|
15329
15562
|
const content = readFileSync13(path, "utf-8");
|
|
@@ -15335,7 +15568,7 @@ class MemorySearch {
|
|
|
15335
15568
|
}
|
|
15336
15569
|
}
|
|
15337
15570
|
}
|
|
15338
|
-
const prefsPath =
|
|
15571
|
+
const prefsPath = join18(this.memoryDir, "preferences.json");
|
|
15339
15572
|
if (existsSync26(prefsPath)) {
|
|
15340
15573
|
try {
|
|
15341
15574
|
const prefs = JSON.parse(readFileSync13(prefsPath, "utf-8"));
|
|
@@ -15357,7 +15590,7 @@ var init_search = __esm(() => {
|
|
|
15357
15590
|
|
|
15358
15591
|
// src/modules/memory/store.ts
|
|
15359
15592
|
import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, appendFileSync as appendFileSync5, existsSync as existsSync27, mkdirSync as mkdirSync13 } from "fs";
|
|
15360
|
-
import { join as
|
|
15593
|
+
import { join as join19 } from "path";
|
|
15361
15594
|
|
|
15362
15595
|
class MemoryStore {
|
|
15363
15596
|
memoryDir;
|
|
@@ -15365,7 +15598,7 @@ class MemoryStore {
|
|
|
15365
15598
|
this.memoryDir = memoryDir;
|
|
15366
15599
|
this.ensureDir();
|
|
15367
15600
|
for (const name of MEMORY_FILES2) {
|
|
15368
|
-
const path =
|
|
15601
|
+
const path = join19(this.memoryDir, `${name}.md`);
|
|
15369
15602
|
if (!existsSync27(path)) {
|
|
15370
15603
|
writeFileSync9(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
|
|
15371
15604
|
|
|
@@ -15379,13 +15612,13 @@ class MemoryStore {
|
|
|
15379
15612
|
}
|
|
15380
15613
|
}
|
|
15381
15614
|
read(name) {
|
|
15382
|
-
const path =
|
|
15615
|
+
const path = join19(this.memoryDir, `${name}.md`);
|
|
15383
15616
|
if (!existsSync27(path))
|
|
15384
15617
|
return "";
|
|
15385
15618
|
return readFileSync14(path, "utf-8");
|
|
15386
15619
|
}
|
|
15387
15620
|
append(name, entry) {
|
|
15388
|
-
const path =
|
|
15621
|
+
const path = join19(this.memoryDir, `${name}.md`);
|
|
15389
15622
|
const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
15390
15623
|
const formatted = `- **${timestamp}** — ${entry}
|
|
15391
15624
|
`;
|
|
@@ -15396,7 +15629,7 @@ class MemoryStore {
|
|
|
15396
15629
|
return searchModule.query(query);
|
|
15397
15630
|
}
|
|
15398
15631
|
prefsPath() {
|
|
15399
|
-
return
|
|
15632
|
+
return join19(this.memoryDir, "preferences.json");
|
|
15400
15633
|
}
|
|
15401
15634
|
getPreferences() {
|
|
15402
15635
|
const path = this.prefsPath();
|
|
@@ -15435,8 +15668,8 @@ var init_store2 = __esm(() => {
|
|
|
15435
15668
|
});
|
|
15436
15669
|
|
|
15437
15670
|
// src/tools/remember.ts
|
|
15438
|
-
import { homedir as
|
|
15439
|
-
import { join as
|
|
15671
|
+
import { homedir as homedir7 } from "os";
|
|
15672
|
+
import { join as join20 } from "path";
|
|
15440
15673
|
var CATEGORIES, rememberTool;
|
|
15441
15674
|
var init_remember = __esm(() => {
|
|
15442
15675
|
init_i18n();
|
|
@@ -15475,7 +15708,7 @@ var init_remember = __esm(() => {
|
|
|
15475
15708
|
if (!CATEGORIES.includes(category)) {
|
|
15476
15709
|
return { success: false, output: t("tool.invalid_params") };
|
|
15477
15710
|
}
|
|
15478
|
-
const memoryDir =
|
|
15711
|
+
const memoryDir = join20(homedir7(), ".mma", "memory");
|
|
15479
15712
|
const store = new MemoryStore(memoryDir);
|
|
15480
15713
|
try {
|
|
15481
15714
|
if (category === "preferences") {
|
|
@@ -15507,8 +15740,8 @@ var init_remember = __esm(() => {
|
|
|
15507
15740
|
});
|
|
15508
15741
|
|
|
15509
15742
|
// src/tools/recall.ts
|
|
15510
|
-
import { homedir as
|
|
15511
|
-
import { join as
|
|
15743
|
+
import { homedir as homedir8 } from "os";
|
|
15744
|
+
import { join as join21 } from "path";
|
|
15512
15745
|
function formatAll(store) {
|
|
15513
15746
|
const parts = [];
|
|
15514
15747
|
const prefs = store.getPreferences();
|
|
@@ -15592,7 +15825,7 @@ var init_recall = __esm(() => {
|
|
|
15592
15825
|
handler: async (_ctx, args) => {
|
|
15593
15826
|
const query = args.query ? String(args.query) : "";
|
|
15594
15827
|
const category = args.category ? String(args.category) : "";
|
|
15595
|
-
const memoryDir =
|
|
15828
|
+
const memoryDir = join21(homedir8(), ".mma", "memory");
|
|
15596
15829
|
const store = new MemoryStore(memoryDir);
|
|
15597
15830
|
try {
|
|
15598
15831
|
if (!query && !category) {
|
|
@@ -15643,13 +15876,13 @@ __export(exports_bridge_client, {
|
|
|
15643
15876
|
});
|
|
15644
15877
|
import { spawn as spawn4 } from "child_process";
|
|
15645
15878
|
import { createInterface } from "readline";
|
|
15646
|
-
import { dirname as dirname10, join as
|
|
15879
|
+
import { dirname as dirname10, join as join22 } from "path";
|
|
15647
15880
|
import { fileURLToPath } from "url";
|
|
15648
15881
|
function bridgeScriptPath() {
|
|
15649
15882
|
const dir = dirname10(fileURLToPath(import.meta.url));
|
|
15650
15883
|
const candidates = [
|
|
15651
|
-
|
|
15652
|
-
|
|
15884
|
+
join22(dir, "bridge-server.mjs"),
|
|
15885
|
+
join22(dir, "modules", "browser", "bridge-server.mjs")
|
|
15653
15886
|
];
|
|
15654
15887
|
return pickExistingPath(candidates);
|
|
15655
15888
|
}
|
|
@@ -16203,15 +16436,15 @@ function buildTextExtractionScript() {
|
|
|
16203
16436
|
|
|
16204
16437
|
// src/modules/browser/cookie-store.ts
|
|
16205
16438
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
16206
|
-
import { join as
|
|
16439
|
+
import { join as join23 } from "path";
|
|
16207
16440
|
|
|
16208
16441
|
class CookieStore {
|
|
16209
16442
|
filePath;
|
|
16210
16443
|
constructor(cookieDir) {
|
|
16211
|
-
this.filePath =
|
|
16444
|
+
this.filePath = join23(cookieDir, "cookies.json");
|
|
16212
16445
|
}
|
|
16213
16446
|
async save(cookies) {
|
|
16214
|
-
await mkdir(
|
|
16447
|
+
await mkdir(join23(this.filePath, ".."), { recursive: true });
|
|
16215
16448
|
await writeFile(this.filePath, JSON.stringify(cookies, null, 2), "utf-8");
|
|
16216
16449
|
}
|
|
16217
16450
|
async load() {
|
|
@@ -16566,10 +16799,10 @@ var init_session = __esm(() => {
|
|
|
16566
16799
|
});
|
|
16567
16800
|
|
|
16568
16801
|
// src/tools/browser.ts
|
|
16569
|
-
import { join as
|
|
16802
|
+
import { join as join24 } from "path";
|
|
16570
16803
|
function getSession(ctx) {
|
|
16571
16804
|
if (!session) {
|
|
16572
|
-
const cookieDir =
|
|
16805
|
+
const cookieDir = join24(ctx.baseDir, ".mma", "browser");
|
|
16573
16806
|
session = new BrowserSession({
|
|
16574
16807
|
...DEFAULT_BROWSER_CONFIG,
|
|
16575
16808
|
headless: ctx.config.browser?.headless ?? true,
|
|
@@ -16717,8 +16950,8 @@ async function readClipboardFallback() {
|
|
|
16717
16950
|
const { platform: platform5 } = await import("os");
|
|
16718
16951
|
const { execSync } = await import("child_process");
|
|
16719
16952
|
const { readFileSync: readFileSync16, unlinkSync: unlinkSync4 } = await import("fs");
|
|
16720
|
-
const { join:
|
|
16721
|
-
const tmpPath =
|
|
16953
|
+
const { join: join25 } = await import("path");
|
|
16954
|
+
const tmpPath = join25(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
|
|
16722
16955
|
try {
|
|
16723
16956
|
if (platform5() === "linux") {
|
|
16724
16957
|
execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, {
|
|
@@ -17100,7 +17333,7 @@ class ModuleRegistry {
|
|
|
17100
17333
|
|
|
17101
17334
|
// src/modules/plugins/loader.ts
|
|
17102
17335
|
import { readdirSync as readdirSync9, existsSync as existsSync30, statSync as statSync5 } from "fs";
|
|
17103
|
-
import { join as
|
|
17336
|
+
import { join as join25, basename as basename3 } from "path";
|
|
17104
17337
|
|
|
17105
17338
|
class PluginLoader {
|
|
17106
17339
|
loadFromDir(dirPath, pluginManager, logger, options) {
|
|
@@ -17108,7 +17341,7 @@ class PluginLoader {
|
|
|
17108
17341
|
return;
|
|
17109
17342
|
const entries = readdirSync9(dirPath).sort();
|
|
17110
17343
|
for (const entry of entries) {
|
|
17111
|
-
const fullPath =
|
|
17344
|
+
const fullPath = join25(dirPath, entry);
|
|
17112
17345
|
const stat = statSync5(fullPath);
|
|
17113
17346
|
if (stat.isFile()) {
|
|
17114
17347
|
if (!entry.endsWith(".ts") && !entry.endsWith(".js"))
|
|
@@ -17124,7 +17357,7 @@ class PluginLoader {
|
|
|
17124
17357
|
}
|
|
17125
17358
|
findEntryFile(dir) {
|
|
17126
17359
|
for (const name of FOLDER_ENTRY_NAMES) {
|
|
17127
|
-
const candidate =
|
|
17360
|
+
const candidate = join25(dir, name);
|
|
17128
17361
|
if (existsSync30(candidate))
|
|
17129
17362
|
return candidate;
|
|
17130
17363
|
}
|
|
@@ -17168,7 +17401,7 @@ var init_loader = __esm(() => {
|
|
|
17168
17401
|
// src/modules/plugins/builtin/lint-on-write.ts
|
|
17169
17402
|
import { spawn as spawn5, execSync } from "child_process";
|
|
17170
17403
|
import { existsSync as existsSync31, readFileSync as readFileSync16 } from "fs";
|
|
17171
|
-
import { resolve as resolve18, extname as extname4, join as
|
|
17404
|
+
import { resolve as resolve18, extname as extname4, join as join26 } from "path";
|
|
17172
17405
|
import { platform as platform5 } from "os";
|
|
17173
17406
|
function contentHash(content) {
|
|
17174
17407
|
let h = 5381;
|
|
@@ -17280,7 +17513,7 @@ class LintOnWritePlugin {
|
|
|
17280
17513
|
}
|
|
17281
17514
|
async runProjectLint(ctx, result, signal) {
|
|
17282
17515
|
try {
|
|
17283
|
-
const packageJsonPath =
|
|
17516
|
+
const packageJsonPath = join26(ctx.baseDir, "package.json");
|
|
17284
17517
|
if (!existsSync31(packageJsonPath)) {
|
|
17285
17518
|
return;
|
|
17286
17519
|
}
|
|
@@ -17306,7 +17539,7 @@ class LintOnWritePlugin {
|
|
|
17306
17539
|
}
|
|
17307
17540
|
async runProjectTypeCheck(filePath, baseDir, result, signal) {
|
|
17308
17541
|
const projectRoot = findProjectRoot(filePath, baseDir, ["tsconfig.json", "package.json"]);
|
|
17309
|
-
const tsconfigPath =
|
|
17542
|
+
const tsconfigPath = join26(projectRoot, "tsconfig.json");
|
|
17310
17543
|
if (!existsSync31(tsconfigPath)) {
|
|
17311
17544
|
return;
|
|
17312
17545
|
}
|
|
@@ -17554,7 +17787,7 @@ var init_tracker = () => {};
|
|
|
17554
17787
|
|
|
17555
17788
|
// src/modules/execution/plan-store.ts
|
|
17556
17789
|
import { readFileSync as readFileSync17, writeFileSync as writeFileSync10, mkdirSync as mkdirSync14, existsSync as existsSync32, readdirSync as readdirSync10, rmSync } from "fs";
|
|
17557
|
-
import { join as
|
|
17790
|
+
import { join as join27 } from "path";
|
|
17558
17791
|
function readPlanFile(path, fallbackBaseDir) {
|
|
17559
17792
|
try {
|
|
17560
17793
|
const raw = readFileSync17(path, "utf-8");
|
|
@@ -17582,7 +17815,7 @@ function listDir(dir, baseDir) {
|
|
|
17582
17815
|
if (!existsSync32(dir))
|
|
17583
17816
|
return [];
|
|
17584
17817
|
const files = readdirSync10(dir).filter((f) => f.endsWith(".json"));
|
|
17585
|
-
return files.map((f) => readPlanFile(
|
|
17818
|
+
return files.map((f) => readPlanFile(join27(dir, f), baseDir)).filter((p) => p !== null);
|
|
17586
17819
|
}
|
|
17587
17820
|
function toMeta(plan, status) {
|
|
17588
17821
|
return {
|
|
@@ -17603,21 +17836,21 @@ class PlanStore {
|
|
|
17603
17836
|
archiveDir;
|
|
17604
17837
|
legacyPath;
|
|
17605
17838
|
constructor(baseDir) {
|
|
17606
|
-
const mmaDir =
|
|
17839
|
+
const mmaDir = join27(baseDir, ".mma");
|
|
17607
17840
|
if (!existsSync32(mmaDir))
|
|
17608
17841
|
mkdirSync14(mmaDir, { recursive: true });
|
|
17609
17842
|
this.baseDir = baseDir;
|
|
17610
|
-
this.plansDir =
|
|
17611
|
-
this.draftsDir =
|
|
17612
|
-
this.archiveDir =
|
|
17613
|
-
this.legacyPath =
|
|
17843
|
+
this.plansDir = join27(mmaDir, "plans");
|
|
17844
|
+
this.draftsDir = join27(this.plansDir, "drafts");
|
|
17845
|
+
this.archiveDir = join27(this.plansDir, "archive");
|
|
17846
|
+
this.legacyPath = join27(mmaDir, LEGACY_FILE);
|
|
17614
17847
|
for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
|
|
17615
17848
|
if (!existsSync32(dir))
|
|
17616
17849
|
mkdirSync14(dir, { recursive: true });
|
|
17617
17850
|
}
|
|
17618
17851
|
}
|
|
17619
17852
|
activePath() {
|
|
17620
|
-
return
|
|
17853
|
+
return join27(this.plansDir, "active.json");
|
|
17621
17854
|
}
|
|
17622
17855
|
saveActive(plan) {
|
|
17623
17856
|
writePlanFile(this.activePath(), plan);
|
|
@@ -17647,14 +17880,14 @@ class PlanStore {
|
|
|
17647
17880
|
rmSync(p, { force: true });
|
|
17648
17881
|
}
|
|
17649
17882
|
saveDraft(plan) {
|
|
17650
|
-
writePlanFile(
|
|
17883
|
+
writePlanFile(join27(this.draftsDir, `${plan.id}.json`), plan);
|
|
17651
17884
|
}
|
|
17652
17885
|
loadDraft(id) {
|
|
17653
|
-
const p =
|
|
17886
|
+
const p = join27(this.draftsDir, `${id}.json`);
|
|
17654
17887
|
return existsSync32(p) ? readPlanFile(p, this.baseDir) : null;
|
|
17655
17888
|
}
|
|
17656
17889
|
removeDraft(id) {
|
|
17657
|
-
const p =
|
|
17890
|
+
const p = join27(this.draftsDir, `${id}.json`);
|
|
17658
17891
|
if (existsSync32(p))
|
|
17659
17892
|
rmSync(p, { force: true });
|
|
17660
17893
|
}
|
|
@@ -17662,7 +17895,7 @@ class PlanStore {
|
|
|
17662
17895
|
return listDir(this.draftsDir, this.baseDir);
|
|
17663
17896
|
}
|
|
17664
17897
|
archivePlan(plan) {
|
|
17665
|
-
writePlanFile(
|
|
17898
|
+
writePlanFile(join27(this.archiveDir, `${plan.id}.json`), plan);
|
|
17666
17899
|
this.removeDraft(plan.id);
|
|
17667
17900
|
const active = this.loadActive();
|
|
17668
17901
|
if (active && active.id === plan.id) {
|
|
@@ -17673,7 +17906,7 @@ class PlanStore {
|
|
|
17673
17906
|
return listDir(this.archiveDir, this.baseDir);
|
|
17674
17907
|
}
|
|
17675
17908
|
removeArchived(id) {
|
|
17676
|
-
const p =
|
|
17909
|
+
const p = join27(this.archiveDir, `${id}.json`);
|
|
17677
17910
|
if (existsSync32(p))
|
|
17678
17911
|
rmSync(p, { force: true });
|
|
17679
17912
|
}
|
|
@@ -17706,12 +17939,12 @@ class PlanStore {
|
|
|
17706
17939
|
this.clearActive();
|
|
17707
17940
|
return "active";
|
|
17708
17941
|
}
|
|
17709
|
-
const draftPath =
|
|
17942
|
+
const draftPath = join27(this.draftsDir, `${id}.json`);
|
|
17710
17943
|
if (existsSync32(draftPath)) {
|
|
17711
17944
|
rmSync(draftPath, { force: true });
|
|
17712
17945
|
return "draft";
|
|
17713
17946
|
}
|
|
17714
|
-
const archivedPath =
|
|
17947
|
+
const archivedPath = join27(this.archiveDir, `${id}.json`);
|
|
17715
17948
|
if (existsSync32(archivedPath)) {
|
|
17716
17949
|
rmSync(archivedPath, { force: true });
|
|
17717
17950
|
return "archived";
|
|
@@ -19185,8 +19418,8 @@ var init_module = __esm(() => {
|
|
|
19185
19418
|
|
|
19186
19419
|
// src/modules/security/session-encryption.ts
|
|
19187
19420
|
import { readFileSync as readFileSync19, writeFileSync as writeFileSync11, existsSync as existsSync34, readdirSync as readdirSync11, unlinkSync as unlinkSync4 } from "fs";
|
|
19188
|
-
import { join as
|
|
19189
|
-
import { homedir as
|
|
19421
|
+
import { join as join28 } from "path";
|
|
19422
|
+
import { homedir as homedir9 } from "os";
|
|
19190
19423
|
|
|
19191
19424
|
class SessionFileEncryptor {
|
|
19192
19425
|
config;
|
|
@@ -19194,7 +19427,7 @@ class SessionFileEncryptor {
|
|
|
19194
19427
|
constructor(config) {
|
|
19195
19428
|
this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
|
|
19196
19429
|
this.encryptor = new ConfigEncryptor({
|
|
19197
|
-
keyPath: config?.keyPath ||
|
|
19430
|
+
keyPath: config?.keyPath || join28(homedir9(), ".mma", ".session-encryption-key")
|
|
19198
19431
|
});
|
|
19199
19432
|
}
|
|
19200
19433
|
isEnabled() {
|
|
@@ -19280,7 +19513,7 @@ class SessionFileEncryptor {
|
|
|
19280
19513
|
return;
|
|
19281
19514
|
const files = readdirSync11(sessionDir);
|
|
19282
19515
|
for (const file of files) {
|
|
19283
|
-
const filePath =
|
|
19516
|
+
const filePath = join28(sessionDir, file);
|
|
19284
19517
|
if (existsSync34(filePath) && !file.endsWith(".enc")) {
|
|
19285
19518
|
try {
|
|
19286
19519
|
const content = readFileSync19(filePath, "utf8");
|
|
@@ -19297,7 +19530,7 @@ class SessionFileEncryptor {
|
|
|
19297
19530
|
const files = readdirSync11(sessionDir);
|
|
19298
19531
|
for (const file of files) {
|
|
19299
19532
|
if (file.endsWith(".enc")) {
|
|
19300
|
-
const encFilePath =
|
|
19533
|
+
const encFilePath = join28(sessionDir, file);
|
|
19301
19534
|
const decFilePath = encFilePath.slice(0, -4);
|
|
19302
19535
|
try {
|
|
19303
19536
|
const content = readFileSync19(encFilePath, "utf8");
|
|
@@ -19330,7 +19563,7 @@ import {
|
|
|
19330
19563
|
writeFileSync as writeFileSync12,
|
|
19331
19564
|
appendFileSync as appendFileSync6
|
|
19332
19565
|
} from "fs";
|
|
19333
|
-
import { join as
|
|
19566
|
+
import { join as join29 } from "path";
|
|
19334
19567
|
import { gzipSync } from "zlib";
|
|
19335
19568
|
|
|
19336
19569
|
class SessionStore {
|
|
@@ -19344,7 +19577,7 @@ class SessionStore {
|
|
|
19344
19577
|
}
|
|
19345
19578
|
}
|
|
19346
19579
|
getSessionDir(id) {
|
|
19347
|
-
return
|
|
19580
|
+
return join29(this.baseDir, id);
|
|
19348
19581
|
}
|
|
19349
19582
|
updateEncryption(config) {
|
|
19350
19583
|
if (config?.enabled) {
|
|
@@ -19360,16 +19593,16 @@ class SessionStore {
|
|
|
19360
19593
|
mkdirSync15(this.baseDir, { recursive: true });
|
|
19361
19594
|
}
|
|
19362
19595
|
sessionDir(id) {
|
|
19363
|
-
return
|
|
19596
|
+
return join29(this.baseDir, id);
|
|
19364
19597
|
}
|
|
19365
19598
|
metaPath(id) {
|
|
19366
|
-
return
|
|
19599
|
+
return join29(this.sessionDir(id), "meta.json");
|
|
19367
19600
|
}
|
|
19368
19601
|
historyPath(id) {
|
|
19369
|
-
return
|
|
19602
|
+
return join29(this.sessionDir(id), "history.jsonl");
|
|
19370
19603
|
}
|
|
19371
19604
|
sessionLogPath(id) {
|
|
19372
|
-
return
|
|
19605
|
+
return join29(this.sessionDir(id), "session.jsonl");
|
|
19373
19606
|
}
|
|
19374
19607
|
sessionExists(id) {
|
|
19375
19608
|
return existsSync35(this.metaPath(id));
|
|
@@ -19523,7 +19756,7 @@ class SessionStore {
|
|
|
19523
19756
|
if (existsSync35(historyPath)) {
|
|
19524
19757
|
const content = readFileSync20(historyPath, "utf-8");
|
|
19525
19758
|
const compressed = gzipSync(content);
|
|
19526
|
-
const gzPath =
|
|
19759
|
+
const gzPath = join29(this.baseDir, `${session2.id}.jsonl.gz`);
|
|
19527
19760
|
writeFileSync12(gzPath, compressed);
|
|
19528
19761
|
rmSync2(historyPath);
|
|
19529
19762
|
}
|
|
@@ -19676,7 +19909,7 @@ class SessionManager {
|
|
|
19676
19909
|
}
|
|
19677
19910
|
}
|
|
19678
19911
|
}
|
|
19679
|
-
var
|
|
19912
|
+
var init_manager4 = __esm(() => {
|
|
19680
19913
|
init_i18n();
|
|
19681
19914
|
init_session_isolation();
|
|
19682
19915
|
});
|
|
@@ -19712,7 +19945,7 @@ var init_module2 = __esm(() => {
|
|
|
19712
19945
|
// src/modules/session/index.ts
|
|
19713
19946
|
var init_session2 = __esm(() => {
|
|
19714
19947
|
init_store3();
|
|
19715
|
-
|
|
19948
|
+
init_manager4();
|
|
19716
19949
|
init_module2();
|
|
19717
19950
|
});
|
|
19718
19951
|
|
|
@@ -19734,8 +19967,8 @@ class ProfileCompressor {
|
|
|
19734
19967
|
|
|
19735
19968
|
// src/modules/user-profile/profile.ts
|
|
19736
19969
|
import { readFileSync as readFileSync21, writeFileSync as writeFileSync13, existsSync as existsSync36, mkdirSync as mkdirSync16 } from "fs";
|
|
19737
|
-
import { join as
|
|
19738
|
-
import { homedir as
|
|
19970
|
+
import { join as join30 } from "path";
|
|
19971
|
+
import { homedir as homedir10, hostname, platform as platform7, type } from "os";
|
|
19739
19972
|
import { env } from "process";
|
|
19740
19973
|
|
|
19741
19974
|
class UserProfile {
|
|
@@ -19751,7 +19984,7 @@ class UserProfile {
|
|
|
19751
19984
|
os: `${type()} ${hostname()}`,
|
|
19752
19985
|
hostname: hostname(),
|
|
19753
19986
|
shell: env.SHELL || env.ComSpec || "unknown",
|
|
19754
|
-
home:
|
|
19987
|
+
home: homedir10(),
|
|
19755
19988
|
nodeVersion: process.version,
|
|
19756
19989
|
preferences: { ...this.preferences }
|
|
19757
19990
|
};
|
|
@@ -19761,10 +19994,10 @@ class UserProfile {
|
|
|
19761
19994
|
if (!existsSync36(this.profileDir)) {
|
|
19762
19995
|
mkdirSync16(this.profileDir, { recursive: true });
|
|
19763
19996
|
}
|
|
19764
|
-
writeFileSync13(
|
|
19997
|
+
writeFileSync13(join30(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
|
|
19765
19998
|
}
|
|
19766
19999
|
load() {
|
|
19767
|
-
const path =
|
|
20000
|
+
const path = join30(this.profileDir, "profile.json");
|
|
19768
20001
|
if (!existsSync36(path))
|
|
19769
20002
|
return null;
|
|
19770
20003
|
try {
|
|
@@ -19804,7 +20037,7 @@ var init_profile = () => {};
|
|
|
19804
20037
|
|
|
19805
20038
|
// src/modules/skills/loader.ts
|
|
19806
20039
|
import { readdirSync as readdirSync13, readFileSync as readFileSync22, existsSync as existsSync37, statSync as statSync6 } from "fs";
|
|
19807
|
-
import { join as
|
|
20040
|
+
import { join as join31 } from "path";
|
|
19808
20041
|
|
|
19809
20042
|
class SkillsLoader {
|
|
19810
20043
|
loadFromDir(dirPath) {
|
|
@@ -19817,7 +20050,7 @@ class SkillsLoader {
|
|
|
19817
20050
|
scanDir(dirPath, skills) {
|
|
19818
20051
|
const entries = readdirSync13(dirPath);
|
|
19819
20052
|
for (const entry of entries) {
|
|
19820
|
-
const fullPath =
|
|
20053
|
+
const fullPath = join31(dirPath, entry);
|
|
19821
20054
|
const stat = statSync6(fullPath);
|
|
19822
20055
|
if (stat.isDirectory()) {
|
|
19823
20056
|
this.scanDir(fullPath, skills);
|
|
@@ -20066,10 +20299,6 @@ import { resolve as resolve20 } from "path";
|
|
|
20066
20299
|
import { platform as platform8 } from "os";
|
|
20067
20300
|
|
|
20068
20301
|
class LspClient {
|
|
20069
|
-
logger = null;
|
|
20070
|
-
setLogger(logger) {
|
|
20071
|
-
this.logger = logger;
|
|
20072
|
-
}
|
|
20073
20302
|
process = null;
|
|
20074
20303
|
requestId = 0;
|
|
20075
20304
|
pending = new Map;
|
|
@@ -20129,25 +20358,11 @@ class LspClient {
|
|
|
20129
20358
|
try {
|
|
20130
20359
|
await this.sendRequest("initialize", initParams, timeout);
|
|
20131
20360
|
} 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
|
-
});
|
|
20137
20361
|
if (!(e instanceof Error) || !e.message.includes("initialize"))
|
|
20138
20362
|
throw e;
|
|
20139
20363
|
await this.shutdown();
|
|
20140
20364
|
await this.startServer(config, projectRoot);
|
|
20141
|
-
|
|
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
|
-
}
|
|
20365
|
+
await this.sendRequest("initialize", initParams, timeout);
|
|
20151
20366
|
}
|
|
20152
20367
|
this.initialized = true;
|
|
20153
20368
|
}
|
|
@@ -20185,11 +20400,8 @@ class LspClient {
|
|
|
20185
20400
|
});
|
|
20186
20401
|
this.process = proc;
|
|
20187
20402
|
setTimeout(() => {
|
|
20188
|
-
if (!this.initialized && this.process)
|
|
20189
|
-
|
|
20190
|
-
this.logger?.error(msg, { command: config.command, projectRoot, timeout: config.timeout ?? 1e4 });
|
|
20191
|
-
reject(new Error(msg));
|
|
20192
|
-
}
|
|
20403
|
+
if (!this.initialized && this.process)
|
|
20404
|
+
reject(new Error("LSP server start timeout"));
|
|
20193
20405
|
}, config.timeout ?? 1e4);
|
|
20194
20406
|
});
|
|
20195
20407
|
}
|
|
@@ -20228,9 +20440,7 @@ class LspClient {
|
|
|
20228
20440
|
try {
|
|
20229
20441
|
const msg = JSON.parse(body);
|
|
20230
20442
|
this.handleMessage(msg);
|
|
20231
|
-
} catch
|
|
20232
|
-
this.logger?.debug(`LSP JSON parse error: ${e instanceof Error ? e.message : String(e)}`);
|
|
20233
|
-
}
|
|
20443
|
+
} catch {}
|
|
20234
20444
|
}
|
|
20235
20445
|
}
|
|
20236
20446
|
handleMessage(msg) {
|
|
@@ -20268,9 +20478,7 @@ class LspClient {
|
|
|
20268
20478
|
setTimeout(() => {
|
|
20269
20479
|
if (this.pending.has(id)) {
|
|
20270
20480
|
this.pending.delete(id);
|
|
20271
|
-
|
|
20272
|
-
this.logger?.warn(msg, { method, timeout });
|
|
20273
|
-
reject(new Error(msg));
|
|
20481
|
+
reject(new Error(`LSP request timeout: ${method}`));
|
|
20274
20482
|
}
|
|
20275
20483
|
}, timeout);
|
|
20276
20484
|
});
|
|
@@ -20280,37 +20488,27 @@ class LspClient {
|
|
|
20280
20488
|
this.write(message);
|
|
20281
20489
|
}
|
|
20282
20490
|
write(message) {
|
|
20283
|
-
if (!this.process?.stdin?.writable)
|
|
20284
|
-
this.logger?.debug("LSP write failed: process stdin not writable");
|
|
20491
|
+
if (!this.process?.stdin?.writable)
|
|
20285
20492
|
return;
|
|
20286
|
-
}
|
|
20287
20493
|
const header = `Content-Length: ${Buffer.byteLength(message)}\r
|
|
20288
20494
|
\r
|
|
20289
20495
|
`;
|
|
20290
20496
|
try {
|
|
20291
20497
|
this.process.stdin.write(header + message);
|
|
20292
|
-
} catch
|
|
20293
|
-
this.logger?.debug(`LSP write error: ${e instanceof Error ? e.message : String(e)}`);
|
|
20294
|
-
}
|
|
20498
|
+
} catch {}
|
|
20295
20499
|
}
|
|
20296
20500
|
async shutdown() {
|
|
20297
20501
|
try {
|
|
20298
20502
|
if (this.process && this.initialized && this.process.stdin?.writable) {
|
|
20299
|
-
this.sendRequest("shutdown", null, 3000).catch((
|
|
20300
|
-
this.logger?.debug(`LSP shutdown request failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
20301
|
-
});
|
|
20503
|
+
this.sendRequest("shutdown", null, 3000).catch(() => {});
|
|
20302
20504
|
this.sendNotification("exit", null);
|
|
20303
20505
|
await new Promise((r) => setTimeout(r, 200));
|
|
20304
20506
|
}
|
|
20305
|
-
} catch
|
|
20306
|
-
this.logger?.debug(`LSP shutdown error: ${e instanceof Error ? e.message : String(e)}`);
|
|
20307
|
-
} finally {
|
|
20507
|
+
} catch {} finally {
|
|
20308
20508
|
if (this.process) {
|
|
20309
20509
|
try {
|
|
20310
20510
|
killTree(this.process);
|
|
20311
|
-
} catch
|
|
20312
|
-
this.logger?.debug(`LSP killTree error: ${e instanceof Error ? e.message : String(e)}`);
|
|
20313
|
-
}
|
|
20511
|
+
} catch {}
|
|
20314
20512
|
this.process = null;
|
|
20315
20513
|
}
|
|
20316
20514
|
this.initialized = false;
|
|
@@ -20418,26 +20616,9 @@ class LspModule {
|
|
|
20418
20616
|
client;
|
|
20419
20617
|
failuresByServer = new Map;
|
|
20420
20618
|
disabledServers = new Set;
|
|
20421
|
-
|
|
20422
|
-
constructor(config, client, logger) {
|
|
20619
|
+
constructor(config, client) {
|
|
20423
20620
|
this.config = { ...DEFAULT_LSP_CONFIG, ...config };
|
|
20424
20621
|
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);
|
|
20441
20622
|
}
|
|
20442
20623
|
isLspDisabled() {
|
|
20443
20624
|
return this.disabledServers.size > 0;
|
|
@@ -20657,7 +20838,7 @@ var init_lsp = __esm(() => {
|
|
|
20657
20838
|
|
|
20658
20839
|
// src/modules/lsp/startup-check.ts
|
|
20659
20840
|
import { existsSync as existsSync39 } from "fs";
|
|
20660
|
-
import { join as
|
|
20841
|
+
import { join as join32 } from "path";
|
|
20661
20842
|
import { spawn as spawn7 } from "child_process";
|
|
20662
20843
|
async function runStartupHealthCheck(config, baseDir, deps = {}) {
|
|
20663
20844
|
if (!config.enabled)
|
|
@@ -20684,7 +20865,7 @@ ${result.lines.join(`
|
|
|
20684
20865
|
}
|
|
20685
20866
|
async function runCheck(config, baseDir, deps) {
|
|
20686
20867
|
const projectRoot = findProjectRoot(baseDir, baseDir, ["tsconfig.json", "package.json"]);
|
|
20687
|
-
if (existsSync39(
|
|
20868
|
+
if (existsSync39(join32(projectRoot, "tsconfig.json"))) {
|
|
20688
20869
|
const runTsc = deps.runTsc ?? runTscDefault;
|
|
20689
20870
|
const errors = await runTsc(projectRoot, STARTUP_CHECK_TIMEOUT_MS);
|
|
20690
20871
|
if (errors.length === 0)
|
|
@@ -20708,9 +20889,7 @@ async function runCheck(config, baseDir, deps) {
|
|
|
20708
20889
|
lines.push(formatStartupError(file, baseDir, d));
|
|
20709
20890
|
}
|
|
20710
20891
|
}
|
|
20711
|
-
} catch
|
|
20712
|
-
deps.logger?.debug(`Startup LSP check failed for ${file}: ${e instanceof Error ? e.message : String(e)}`);
|
|
20713
|
-
}
|
|
20892
|
+
} catch {}
|
|
20714
20893
|
}
|
|
20715
20894
|
if (checked === 0 || lines.length === 0)
|
|
20716
20895
|
return null;
|
|
@@ -20783,7 +20962,7 @@ var init_startup_check = __esm(() => {
|
|
|
20783
20962
|
|
|
20784
20963
|
// src/modules/indexer/walker.ts
|
|
20785
20964
|
import { readdirSync as readdirSync14, readFileSync as readFileSync23, statSync as statSync7, existsSync as existsSync40, watch } from "fs";
|
|
20786
|
-
import { join as
|
|
20965
|
+
import { join as join33, relative as relative4, extname as extname5 } from "path";
|
|
20787
20966
|
|
|
20788
20967
|
class Indexer {
|
|
20789
20968
|
baseDir;
|
|
@@ -20821,7 +21000,7 @@ class Indexer {
|
|
|
20821
21000
|
for (const entry of entries) {
|
|
20822
21001
|
if (count >= this.MAX_FILES)
|
|
20823
21002
|
return;
|
|
20824
|
-
const fullPath =
|
|
21003
|
+
const fullPath = join33(dir, entry);
|
|
20825
21004
|
const relPath = relative4(this.baseDir, fullPath);
|
|
20826
21005
|
const stat2 = statSync7(fullPath);
|
|
20827
21006
|
if (stat2.isDirectory()) {
|
|
@@ -20885,13 +21064,13 @@ var init_walker = __esm(() => {
|
|
|
20885
21064
|
|
|
20886
21065
|
// src/modules/indexer/cache.ts
|
|
20887
21066
|
import { readFileSync as readFileSync24, writeFileSync as writeFileSync14, existsSync as existsSync41, mkdirSync as mkdirSync17, rmSync as rmSync3 } from "fs";
|
|
20888
|
-
import { join as
|
|
21067
|
+
import { join as join34 } from "path";
|
|
20889
21068
|
|
|
20890
21069
|
class IndexCache {
|
|
20891
21070
|
cachePath;
|
|
20892
21071
|
cache = null;
|
|
20893
21072
|
constructor(cacheDir) {
|
|
20894
|
-
this.cachePath =
|
|
21073
|
+
this.cachePath = join34(cacheDir, "index-cache.json");
|
|
20895
21074
|
}
|
|
20896
21075
|
load() {
|
|
20897
21076
|
if (this.cache)
|
|
@@ -20907,7 +21086,7 @@ class IndexCache {
|
|
|
20907
21086
|
}
|
|
20908
21087
|
save(result) {
|
|
20909
21088
|
this.cache = result;
|
|
20910
|
-
const dir =
|
|
21089
|
+
const dir = join34(this.cachePath, "..");
|
|
20911
21090
|
if (!existsSync41(dir))
|
|
20912
21091
|
mkdirSync17(dir, { recursive: true });
|
|
20913
21092
|
writeFileSync14(this.cachePath, JSON.stringify(result), "utf-8");
|
|
@@ -20925,10 +21104,10 @@ var init_cache = () => {};
|
|
|
20925
21104
|
|
|
20926
21105
|
// src/modules/indexer/project-profile.ts
|
|
20927
21106
|
import { readFileSync as readFileSync25, existsSync as existsSync42 } from "fs";
|
|
20928
|
-
import { join as
|
|
21107
|
+
import { join as join35 } from "path";
|
|
20929
21108
|
function detectManifest(baseDir) {
|
|
20930
21109
|
for (const manifest of MANIFEST_ORDER) {
|
|
20931
|
-
if (existsSync42(
|
|
21110
|
+
if (existsSync42(join35(baseDir, manifest)))
|
|
20932
21111
|
return manifest;
|
|
20933
21112
|
}
|
|
20934
21113
|
return null;
|
|
@@ -20945,7 +21124,7 @@ function cleanDependency(entry) {
|
|
|
20945
21124
|
}
|
|
20946
21125
|
function readPackageJson(baseDir) {
|
|
20947
21126
|
try {
|
|
20948
|
-
const raw = JSON.parse(readFileSync25(
|
|
21127
|
+
const raw = JSON.parse(readFileSync25(join35(baseDir, "package.json"), "utf-8"));
|
|
20949
21128
|
if (!raw || typeof raw !== "object")
|
|
20950
21129
|
return null;
|
|
20951
21130
|
const profile = {
|
|
@@ -20969,7 +21148,7 @@ function readPackageJson(baseDir) {
|
|
|
20969
21148
|
}
|
|
20970
21149
|
function readPyproject(baseDir) {
|
|
20971
21150
|
try {
|
|
20972
|
-
const content = readFileSync25(
|
|
21151
|
+
const content = readFileSync25(join35(baseDir, "pyproject.toml"), "utf-8");
|
|
20973
21152
|
const profile = { runtime: "python", deps: [], devDeps: [], scripts: {} };
|
|
20974
21153
|
const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
|
|
20975
21154
|
if (nameMatch)
|
|
@@ -20985,7 +21164,7 @@ function readPyproject(baseDir) {
|
|
|
20985
21164
|
}
|
|
20986
21165
|
function readCargo(baseDir) {
|
|
20987
21166
|
try {
|
|
20988
|
-
const content = readFileSync25(
|
|
21167
|
+
const content = readFileSync25(join35(baseDir, "Cargo.toml"), "utf-8");
|
|
20989
21168
|
const profile = { runtime: "rust", deps: [], devDeps: [], scripts: {} };
|
|
20990
21169
|
const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
|
|
20991
21170
|
if (nameMatch)
|
|
@@ -21009,7 +21188,7 @@ function readCargo(baseDir) {
|
|
|
21009
21188
|
}
|
|
21010
21189
|
function readGoMod(baseDir) {
|
|
21011
21190
|
try {
|
|
21012
|
-
const content = readFileSync25(
|
|
21191
|
+
const content = readFileSync25(join35(baseDir, "go.mod"), "utf-8");
|
|
21013
21192
|
const profile = { runtime: "go", deps: [], devDeps: [], scripts: {} };
|
|
21014
21193
|
const moduleMatch = content.match(/^module\s+(\S+)/m);
|
|
21015
21194
|
if (moduleMatch)
|
|
@@ -21027,7 +21206,7 @@ function readGoMod(baseDir) {
|
|
|
21027
21206
|
}
|
|
21028
21207
|
function readRequirements(baseDir) {
|
|
21029
21208
|
try {
|
|
21030
|
-
const content = readFileSync25(
|
|
21209
|
+
const content = readFileSync25(join35(baseDir, "requirements.txt"), "utf-8");
|
|
21031
21210
|
const profile = { runtime: "python", deps: [], devDeps: [], scripts: {} };
|
|
21032
21211
|
for (const line of content.split(`
|
|
21033
21212
|
`)) {
|
|
@@ -21485,8 +21664,8 @@ var init_mcp = __esm(() => {
|
|
|
21485
21664
|
});
|
|
21486
21665
|
|
|
21487
21666
|
// src/modules/memory/module.ts
|
|
21488
|
-
import { homedir as
|
|
21489
|
-
import { join as
|
|
21667
|
+
import { homedir as homedir11 } from "os";
|
|
21668
|
+
import { join as join36 } from "path";
|
|
21490
21669
|
|
|
21491
21670
|
class MemoryModule {
|
|
21492
21671
|
name = "memory";
|
|
@@ -21495,7 +21674,7 @@ class MemoryModule {
|
|
|
21495
21674
|
if (storeOrDir instanceof MemoryStore) {
|
|
21496
21675
|
this.store = storeOrDir;
|
|
21497
21676
|
} else {
|
|
21498
|
-
const dir = storeOrDir ||
|
|
21677
|
+
const dir = storeOrDir || join36(homedir11(), ".mma", "memory");
|
|
21499
21678
|
this.store = new MemoryStore(dir);
|
|
21500
21679
|
}
|
|
21501
21680
|
}
|
|
@@ -21582,11 +21761,11 @@ var init_module8 = __esm(() => {
|
|
|
21582
21761
|
|
|
21583
21762
|
// src/core/version.ts
|
|
21584
21763
|
import { existsSync as existsSync43, readFileSync as readFileSync26 } from "fs";
|
|
21585
|
-
import { join as
|
|
21764
|
+
import { join as join37, dirname as dirname13 } from "path";
|
|
21586
21765
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
21587
21766
|
function readMmaVersion() {
|
|
21588
21767
|
const here = dirname13(fileURLToPath2(import.meta.url));
|
|
21589
|
-
const candidates = [
|
|
21768
|
+
const candidates = [join37(here, "..", "..", "package.json"), join37(here, "..", "package.json")];
|
|
21590
21769
|
for (const p of candidates) {
|
|
21591
21770
|
if (existsSync43(p)) {
|
|
21592
21771
|
try {
|
|
@@ -21600,188 +21779,6 @@ function readMmaVersion() {
|
|
|
21600
21779
|
}
|
|
21601
21780
|
var init_version = () => {};
|
|
21602
21781
|
|
|
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
|
-
|
|
21785
21782
|
// src/core/bootstrap.ts
|
|
21786
21783
|
var exports_bootstrap = {};
|
|
21787
21784
|
__export(exports_bootstrap, {
|
|
@@ -21790,7 +21787,7 @@ __export(exports_bootstrap, {
|
|
|
21790
21787
|
});
|
|
21791
21788
|
import { homedir as homedir12 } from "os";
|
|
21792
21789
|
import { join as join38, resolve as resolve23 } from "path";
|
|
21793
|
-
import { existsSync as
|
|
21790
|
+
import { existsSync as existsSync44, readFileSync as readFileSync27, writeFileSync as writeFileSync15 } from "fs";
|
|
21794
21791
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
21795
21792
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
21796
21793
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -21852,25 +21849,14 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21852
21849
|
const profile = new UserProfile(join38(dir));
|
|
21853
21850
|
profile.load() || profile.collect();
|
|
21854
21851
|
profile.save();
|
|
21855
|
-
const
|
|
21856
|
-
model: config.model,
|
|
21857
|
-
baseUrl: config.provider.baseUrl,
|
|
21858
|
-
apiKey: config.provider.apiKey,
|
|
21852
|
+
const providerManager = new ProviderManager(config.provider, {
|
|
21859
21853
|
contextWindow: config.contextWindow,
|
|
21860
21854
|
retry: config.retry,
|
|
21861
21855
|
rateLimits: config.security?.rateLimits
|
|
21862
21856
|
});
|
|
21857
|
+
providerManager.setModel(config.model);
|
|
21858
|
+
const llmProvider = providerManager.active;
|
|
21863
21859
|
const baseDir = projectDir ? resolve23(projectDir) : process.cwd();
|
|
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
21860
|
const projectMapCacheDir = join38(baseDir, ".mma");
|
|
21875
21861
|
const indexerModule = new IndexerModule({
|
|
21876
21862
|
baseDir,
|
|
@@ -21901,7 +21887,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21901
21887
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
21902
21888
|
};
|
|
21903
21889
|
const agentsMdGlobal = join38(dir, "AGENTS.md");
|
|
21904
|
-
if (!
|
|
21890
|
+
if (!existsSync44(agentsMdGlobal)) {
|
|
21905
21891
|
writeFileSync15(agentsMdGlobal, "", "utf-8");
|
|
21906
21892
|
}
|
|
21907
21893
|
const sessionDir = join38(dir, "sessions");
|
|
@@ -21993,7 +21979,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
21993
21979
|
pluginManager.register(browserPlugin);
|
|
21994
21980
|
}
|
|
21995
21981
|
}
|
|
21996
|
-
const lspModule = new LspModule(config.lsp
|
|
21982
|
+
const lspModule = new LspModule(config.lsp);
|
|
21997
21983
|
moduleRegistry.register(lspModule);
|
|
21998
21984
|
const lspPlugin = lspModule.getPlugin();
|
|
21999
21985
|
if (lspPlugin) {
|
|
@@ -22066,8 +22052,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
22066
22052
|
join38(dir, "AGENTS.md")
|
|
22067
22053
|
];
|
|
22068
22054
|
for (const p of agentsMdCandidates) {
|
|
22069
|
-
if (
|
|
22070
|
-
const content =
|
|
22055
|
+
if (existsSync44(p)) {
|
|
22056
|
+
const content = readFileSync27(p, "utf-8").trim();
|
|
22071
22057
|
if (content) {
|
|
22072
22058
|
agentsMdBlocks.push({
|
|
22073
22059
|
content,
|
|
@@ -22087,6 +22073,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
22087
22073
|
const agentDeps = {
|
|
22088
22074
|
config,
|
|
22089
22075
|
llmProvider,
|
|
22076
|
+
providerManager,
|
|
22090
22077
|
toolExecutor,
|
|
22091
22078
|
pluginManager,
|
|
22092
22079
|
contextManager,
|
|
@@ -22145,15 +22132,15 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
22145
22132
|
var init_bootstrap = __esm(() => {
|
|
22146
22133
|
init_config2();
|
|
22147
22134
|
init_app_logger();
|
|
22148
|
-
|
|
22135
|
+
init_providers();
|
|
22149
22136
|
init_tools();
|
|
22150
22137
|
init_hidden_tools_block();
|
|
22151
22138
|
init_executor();
|
|
22152
|
-
|
|
22139
|
+
init_manager3();
|
|
22153
22140
|
init_loader();
|
|
22154
22141
|
init_lint_on_write();
|
|
22155
22142
|
init_notify();
|
|
22156
|
-
|
|
22143
|
+
init_manager2();
|
|
22157
22144
|
init_token_counter();
|
|
22158
22145
|
init_detector();
|
|
22159
22146
|
init_module();
|
|
@@ -22170,7 +22157,6 @@ var init_bootstrap = __esm(() => {
|
|
|
22170
22157
|
init_i18n();
|
|
22171
22158
|
init_agent();
|
|
22172
22159
|
init_version();
|
|
22173
|
-
init_environment();
|
|
22174
22160
|
});
|
|
22175
22161
|
|
|
22176
22162
|
// node_modules/ansi-regex/index.js
|
|
@@ -22897,35 +22883,24 @@ async function runSetup(externalRl) {
|
|
|
22897
22883
|
console.log(l);
|
|
22898
22884
|
return answers;
|
|
22899
22885
|
}
|
|
22900
|
-
var PROVIDER_TYPES, KNOWN_PORTS
|
|
22886
|
+
var PROVIDER_TYPES, KNOWN_PORTS;
|
|
22901
22887
|
var init_setup = __esm(() => {
|
|
22902
22888
|
init_colors();
|
|
22903
22889
|
init_i18n();
|
|
22904
22890
|
init_spinner();
|
|
22891
|
+
init_presets();
|
|
22905
22892
|
init_box();
|
|
22906
22893
|
init_table();
|
|
22907
|
-
PROVIDER_TYPES =
|
|
22908
|
-
|
|
22909
|
-
|
|
22910
|
-
|
|
22911
|
-
},
|
|
22912
|
-
{ value: "openai", label: "OpenAI API" },
|
|
22913
|
-
{ value: "anthropic", label: "Anthropic Claude" },
|
|
22914
|
-
{ value: "opencode-zen", label: "OpenCode Zen (opencode.ai/zen)" },
|
|
22915
|
-
{ value: "opencode-go", label: "OpenCode Go (opencode.ai/go)" }
|
|
22916
|
-
];
|
|
22894
|
+
PROVIDER_TYPES = BUILTIN_PROVIDERS.map((spec) => ({
|
|
22895
|
+
value: spec.type,
|
|
22896
|
+
label: spec.label
|
|
22897
|
+
}));
|
|
22917
22898
|
KNOWN_PORTS = [
|
|
22918
22899
|
{ port: 1234, label: "LM Studio" },
|
|
22919
22900
|
{ port: 11434, label: "Ollama" },
|
|
22920
22901
|
{ port: 8080, label: "vLLM / custom" },
|
|
22921
22902
|
{ port: 4891, label: "GPT4All" }
|
|
22922
22903
|
];
|
|
22923
|
-
HOSTED_BASE_URLS = {
|
|
22924
|
-
openai: "https://api.openai.com/v1",
|
|
22925
|
-
anthropic: "https://api.anthropic.com",
|
|
22926
|
-
"opencode-zen": "https://opencode.ai/zen/v1",
|
|
22927
|
-
"opencode-go": "https://opencode.ai/zen/go/v1"
|
|
22928
|
-
};
|
|
22929
22904
|
});
|
|
22930
22905
|
|
|
22931
22906
|
// src/modules/certification/manifest.ts
|
|
@@ -22939,13 +22914,13 @@ __export(exports_manifest, {
|
|
|
22939
22914
|
getCertMark: () => getCertMark,
|
|
22940
22915
|
MANIFEST_PATH: () => MANIFEST_PATH
|
|
22941
22916
|
});
|
|
22942
|
-
import { existsSync as
|
|
22917
|
+
import { existsSync as existsSync45, readFileSync as readFileSync28, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
22943
22918
|
import { homedir as homedir14 } from "os";
|
|
22944
22919
|
import { join as join40 } from "path";
|
|
22945
22920
|
function readManifest(path = MANIFEST_PATH) {
|
|
22946
22921
|
try {
|
|
22947
|
-
if (
|
|
22948
|
-
const raw = JSON.parse(
|
|
22922
|
+
if (existsSync45(path)) {
|
|
22923
|
+
const raw = JSON.parse(readFileSync28(path, "utf-8"));
|
|
22949
22924
|
return { version: 1, certifications: raw.certifications ?? [] };
|
|
22950
22925
|
}
|
|
22951
22926
|
} catch {}
|
|
@@ -30110,7 +30085,7 @@ var init_scenarios = __esm(() => {
|
|
|
30110
30085
|
});
|
|
30111
30086
|
|
|
30112
30087
|
// src/modules/certification/loader.ts
|
|
30113
|
-
import { existsSync as
|
|
30088
|
+
import { existsSync as existsSync46, readdirSync as readdirSync15, readFileSync as readFileSync29 } from "fs";
|
|
30114
30089
|
import { join as join41 } from "path";
|
|
30115
30090
|
function validateScenario(s) {
|
|
30116
30091
|
const errors2 = [];
|
|
@@ -30160,12 +30135,12 @@ function loadScenarios(userDir) {
|
|
|
30160
30135
|
else
|
|
30161
30136
|
scenarios.push(s);
|
|
30162
30137
|
}
|
|
30163
|
-
if (userDir &&
|
|
30164
|
-
for (const file of
|
|
30138
|
+
if (userDir && existsSync46(userDir)) {
|
|
30139
|
+
for (const file of readdirSync15(userDir)) {
|
|
30165
30140
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
30166
30141
|
continue;
|
|
30167
30142
|
try {
|
|
30168
|
-
const raw =
|
|
30143
|
+
const raw = readFileSync29(join41(userDir, file), "utf-8");
|
|
30169
30144
|
const data = $parse(raw);
|
|
30170
30145
|
const parsed = normalizeScenario(data, file);
|
|
30171
30146
|
const errs = validateScenario(parsed);
|
|
@@ -30218,7 +30193,7 @@ var init_loader3 = __esm(() => {
|
|
|
30218
30193
|
});
|
|
30219
30194
|
|
|
30220
30195
|
// src/modules/certification/fact-checker.ts
|
|
30221
|
-
import { existsSync as
|
|
30196
|
+
import { existsSync as existsSync47, readFileSync as readFileSync30, statSync as statSync8 } from "fs";
|
|
30222
30197
|
import { join as join42 } from "path";
|
|
30223
30198
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
30224
30199
|
const failures = [];
|
|
@@ -30238,14 +30213,14 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
30238
30213
|
case "fileExists":
|
|
30239
30214
|
return isFile(join42(sandboxDir, check.path));
|
|
30240
30215
|
case "fileNotExists":
|
|
30241
|
-
return !
|
|
30216
|
+
return !existsSync47(join42(sandboxDir, check.path));
|
|
30242
30217
|
case "dirExists":
|
|
30243
30218
|
return isDir(join42(sandboxDir, check.path));
|
|
30244
30219
|
case "fileContent": {
|
|
30245
30220
|
const abs = join42(sandboxDir, check.path);
|
|
30246
30221
|
if (!isFile(abs))
|
|
30247
30222
|
return false;
|
|
30248
|
-
const content =
|
|
30223
|
+
const content = readFileSync30(abs, "utf-8");
|
|
30249
30224
|
if (check.contains !== undefined)
|
|
30250
30225
|
return content.includes(check.contains);
|
|
30251
30226
|
if (check.equals !== undefined)
|
|
@@ -30256,7 +30231,7 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
30256
30231
|
const abs = join42(sandboxDir, check.path);
|
|
30257
30232
|
if (!isFile(abs))
|
|
30258
30233
|
return false;
|
|
30259
|
-
return new RegExp(check.pattern).test(
|
|
30234
|
+
return new RegExp(check.pattern).test(readFileSync30(abs, "utf-8"));
|
|
30260
30235
|
}
|
|
30261
30236
|
default:
|
|
30262
30237
|
return false;
|
|
@@ -30264,14 +30239,14 @@ function runCheck2(sandboxDir, check, exitCode, output) {
|
|
|
30264
30239
|
}
|
|
30265
30240
|
function isFile(p) {
|
|
30266
30241
|
try {
|
|
30267
|
-
return
|
|
30242
|
+
return existsSync47(p) && statSync8(p).isFile();
|
|
30268
30243
|
} catch {
|
|
30269
30244
|
return false;
|
|
30270
30245
|
}
|
|
30271
30246
|
}
|
|
30272
30247
|
function isDir(p) {
|
|
30273
30248
|
try {
|
|
30274
|
-
return
|
|
30249
|
+
return existsSync47(p) && statSync8(p).isDirectory();
|
|
30275
30250
|
} catch {
|
|
30276
30251
|
return false;
|
|
30277
30252
|
}
|
|
@@ -30302,9 +30277,9 @@ var init_fact_checker = () => {};
|
|
|
30302
30277
|
|
|
30303
30278
|
// src/modules/certification/runner.ts
|
|
30304
30279
|
import { spawn as spawn8 } from "child_process";
|
|
30305
|
-
import { existsSync as
|
|
30306
|
-
import { platform as
|
|
30307
|
-
import { join as join43, resolve as resolve24, dirname as
|
|
30280
|
+
import { existsSync as existsSync48, mkdirSync as mkdirSync19, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
|
|
30281
|
+
import { platform as platform9 } from "os";
|
|
30282
|
+
import { join as join43, resolve as resolve24, dirname as dirname14 } from "path";
|
|
30308
30283
|
async function runScenario(scenario, opts) {
|
|
30309
30284
|
if (scenario.mode === "skip") {
|
|
30310
30285
|
return {
|
|
@@ -30337,15 +30312,15 @@ async function runScenario(scenario, opts) {
|
|
|
30337
30312
|
sandbox,
|
|
30338
30313
|
scenario.prompt
|
|
30339
30314
|
];
|
|
30340
|
-
const
|
|
30315
|
+
const env2 = {
|
|
30341
30316
|
...process.env,
|
|
30342
30317
|
MMA_MODEL: opts.model,
|
|
30343
30318
|
MMA_PROVIDER_BASEURL: opts.providerUrl,
|
|
30344
30319
|
MMA_CONTEXT_WINDOW: String(opts.contextWindow ?? 32000)
|
|
30345
30320
|
};
|
|
30346
30321
|
if (opts.providerKey)
|
|
30347
|
-
|
|
30348
|
-
const res = await runner(
|
|
30322
|
+
env2.MMA_PROVIDER_APIKEY = opts.providerKey;
|
|
30323
|
+
const res = await runner(env2, opts.mmaRoot, args, timeoutMs);
|
|
30349
30324
|
output = `${res.stdout}
|
|
30350
30325
|
${res.stderr}`;
|
|
30351
30326
|
exitCode = res.code ?? -1;
|
|
@@ -30385,24 +30360,24 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
|
30385
30360
|
mkdirSync19(sandbox, { recursive: true });
|
|
30386
30361
|
for (const f of scenario.fixtures ?? []) {
|
|
30387
30362
|
const src = join43(mmaRoot, f.source);
|
|
30388
|
-
if (!
|
|
30363
|
+
if (!existsSync48(src)) {
|
|
30389
30364
|
throw new Error(`fixture missing: ${f.source}`);
|
|
30390
30365
|
}
|
|
30391
30366
|
const dest = join43(sandbox, f.dest);
|
|
30392
|
-
mkdirSync19(
|
|
30367
|
+
mkdirSync19(dirname14(dest), { recursive: true });
|
|
30393
30368
|
cpSync2(src, dest);
|
|
30394
30369
|
}
|
|
30395
30370
|
}
|
|
30396
30371
|
function resolveMmaEntry(mmaRoot) {
|
|
30397
30372
|
const dev = join43(mmaRoot, "src", "cli", "main.ts");
|
|
30398
|
-
if (
|
|
30373
|
+
if (existsSync48(dev))
|
|
30399
30374
|
return dev;
|
|
30400
30375
|
return join43(mmaRoot, "dist", "main.js");
|
|
30401
30376
|
}
|
|
30402
30377
|
function findMmaRoot(fromDir) {
|
|
30403
30378
|
const candidates = [resolve24(fromDir, "..", "..", ".."), resolve24(fromDir, "..")];
|
|
30404
30379
|
for (const c of candidates) {
|
|
30405
|
-
if (
|
|
30380
|
+
if (existsSync48(join43(c, "package.json")))
|
|
30406
30381
|
return c;
|
|
30407
30382
|
}
|
|
30408
30383
|
return process.cwd();
|
|
@@ -30411,7 +30386,7 @@ function killTree2(child) {
|
|
|
30411
30386
|
const pid = child.pid;
|
|
30412
30387
|
if (!pid)
|
|
30413
30388
|
return;
|
|
30414
|
-
if (
|
|
30389
|
+
if (platform9() === "win32") {
|
|
30415
30390
|
spawn8("taskkill", ["/pid", String(pid), "/T", "/F"], {
|
|
30416
30391
|
windowsHide: true,
|
|
30417
30392
|
stdio: "ignore"
|
|
@@ -30426,10 +30401,10 @@ function killTree2(child) {
|
|
|
30426
30401
|
} catch {}
|
|
30427
30402
|
}
|
|
30428
30403
|
}
|
|
30429
|
-
var defaultRunner2 = (
|
|
30404
|
+
var defaultRunner2 = (env2, cwd, args, timeoutMs) => new Promise((resolvePromise) => {
|
|
30430
30405
|
const child = spawn8(process.execPath, args, {
|
|
30431
30406
|
cwd,
|
|
30432
|
-
env:
|
|
30407
|
+
env: env2,
|
|
30433
30408
|
windowsHide: true,
|
|
30434
30409
|
stdio: ["ignore", "pipe", "pipe"]
|
|
30435
30410
|
});
|
|
@@ -30470,15 +30445,15 @@ __export(exports_cli, {
|
|
|
30470
30445
|
});
|
|
30471
30446
|
import { rmSync as rmSync5 } from "fs";
|
|
30472
30447
|
import { homedir as homedir15 } from "os";
|
|
30473
|
-
import { join as join44, dirname as
|
|
30474
|
-
import { fileURLToPath as
|
|
30475
|
-
import { existsSync as
|
|
30448
|
+
import { join as join44, dirname as dirname15 } from "path";
|
|
30449
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
30450
|
+
import { existsSync as existsSync49, readFileSync as readFileSync31 } from "fs";
|
|
30476
30451
|
function readVersion() {
|
|
30477
30452
|
const candidates = [join44(MMA_ROOT, "package.json")];
|
|
30478
30453
|
for (const p of candidates) {
|
|
30479
|
-
if (
|
|
30454
|
+
if (existsSync49(p)) {
|
|
30480
30455
|
try {
|
|
30481
|
-
const raw = JSON.parse(
|
|
30456
|
+
const raw = JSON.parse(readFileSync31(p, "utf-8"));
|
|
30482
30457
|
if (raw.version)
|
|
30483
30458
|
return raw.version;
|
|
30484
30459
|
} catch {}
|
|
@@ -30626,7 +30601,7 @@ var init_cli = __esm(() => {
|
|
|
30626
30601
|
init_loader3();
|
|
30627
30602
|
init_runner2();
|
|
30628
30603
|
init_manifest();
|
|
30629
|
-
HERE =
|
|
30604
|
+
HERE = dirname15(fileURLToPath3(import.meta.url));
|
|
30630
30605
|
MMA_ROOT = findMmaRoot(HERE);
|
|
30631
30606
|
USER_SCENARIO_DIR = join44(homedir15(), ".mma", "certification", "scenarios");
|
|
30632
30607
|
});
|
|
@@ -30637,17 +30612,17 @@ __export(exports_repl_commands, {
|
|
|
30637
30612
|
registerAllCommands: () => registerAllCommands,
|
|
30638
30613
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
30639
30614
|
});
|
|
30640
|
-
import { join as join46, dirname as
|
|
30615
|
+
import { join as join46, dirname as dirname17 } from "path";
|
|
30641
30616
|
import { homedir as homedir17 } from "os";
|
|
30642
|
-
import { existsSync as
|
|
30643
|
-
import { fileURLToPath as
|
|
30617
|
+
import { existsSync as existsSync51, readFileSync as readFileSync33 } from "fs";
|
|
30618
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
30644
30619
|
function readVersion3() {
|
|
30645
|
-
const here =
|
|
30620
|
+
const here = dirname17(fileURLToPath5(import.meta.url));
|
|
30646
30621
|
const candidates = [join46(here, "..", "..", "package.json"), join46(here, "..", "package.json")];
|
|
30647
30622
|
for (const p of candidates) {
|
|
30648
|
-
if (
|
|
30623
|
+
if (existsSync51(p)) {
|
|
30649
30624
|
try {
|
|
30650
|
-
const raw = JSON.parse(
|
|
30625
|
+
const raw = JSON.parse(readFileSync33(p, "utf8"));
|
|
30651
30626
|
if (raw.version)
|
|
30652
30627
|
return raw.version;
|
|
30653
30628
|
} catch {}
|
|
@@ -30711,7 +30686,7 @@ function registerMmaCommands(ctx) {
|
|
|
30711
30686
|
}
|
|
30712
30687
|
try {
|
|
30713
30688
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
30714
|
-
const { existsSync:
|
|
30689
|
+
const { existsSync: existsSync52 } = await import("fs");
|
|
30715
30690
|
const { resolve: resolve25 } = await import("path");
|
|
30716
30691
|
let dataUrl;
|
|
30717
30692
|
let label;
|
|
@@ -30731,7 +30706,7 @@ function registerMmaCommands(ctx) {
|
|
|
30731
30706
|
label = source;
|
|
30732
30707
|
} else {
|
|
30733
30708
|
const absPath = resolve25(process.cwd(), source);
|
|
30734
|
-
if (!
|
|
30709
|
+
if (!existsSync52(absPath)) {
|
|
30735
30710
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
30736
30711
|
return;
|
|
30737
30712
|
}
|
|
@@ -30765,7 +30740,13 @@ function registerMmaCommands(ctx) {
|
|
|
30765
30740
|
const sys = Math.floor(ctxW * cfg.contextBudget.systemPrompt);
|
|
30766
30741
|
const res = Math.floor(ctxW * cfg.contextBudget.responseReserve);
|
|
30767
30742
|
console.log(`${t("repl.model")} ${cfg.model}`);
|
|
30768
|
-
|
|
30743
|
+
const providers = ctx.agent.listProviders();
|
|
30744
|
+
const active = providers.find((p) => p.active);
|
|
30745
|
+
if (active) {
|
|
30746
|
+
console.log(`${t("repl.provider")} ${active.label} (${pc2.dim(active.type)}) → ${pc2.dim(active.baseUrl)}`);
|
|
30747
|
+
} else {
|
|
30748
|
+
console.log(`${t("repl.provider")} ${cfg.provider.type} → ${cfg.provider.baseUrl}`);
|
|
30749
|
+
}
|
|
30769
30750
|
console.log(`${t("repl.context")} ${ctxW} (sys:${sys} res:${res} hist:${ctxW - sys - res})`);
|
|
30770
30751
|
console.log(`${t("repl.max_iters")} ${cfg.maxToolIterations}`);
|
|
30771
30752
|
console.log(`${t("repl.stuck_thresh")} ${cfg.stuckThreshold}`);
|
|
@@ -30793,8 +30774,14 @@ function registerMmaCommands(ctx) {
|
|
|
30793
30774
|
description: t("repl.status"),
|
|
30794
30775
|
usage: t("repl.status_usage"),
|
|
30795
30776
|
action: () => {
|
|
30777
|
+
const providers = ctx.agent.listProviders();
|
|
30778
|
+
const active = providers.find((p) => p.active);
|
|
30796
30779
|
console.log(`${t("repl.model")} ${ctx.config.model}`);
|
|
30797
|
-
|
|
30780
|
+
if (active) {
|
|
30781
|
+
console.log(`${t("repl.provider")} ${active.label} (${pc2.dim(active.type)}) @ ${pc2.dim(active.baseUrl)}`);
|
|
30782
|
+
} else {
|
|
30783
|
+
console.log(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
|
|
30784
|
+
}
|
|
30798
30785
|
const meta = ctx.sessionManager?.getActiveMeta();
|
|
30799
30786
|
if (meta) {
|
|
30800
30787
|
console.log(`${t("repl.session_label")} ${meta.name} (${meta.id}) — ${meta.messageCount} messages`);
|
|
@@ -30853,8 +30840,17 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
30853
30840
|
action: async (args) => {
|
|
30854
30841
|
const subcmd = args[0];
|
|
30855
30842
|
if (!subcmd || subcmd === "list") {
|
|
30856
|
-
|
|
30857
|
-
|
|
30843
|
+
const providers = ctx.agent.listProviders();
|
|
30844
|
+
if (providers.length === 0) {
|
|
30845
|
+
console.log(`${t("repl.provider_current")} ${ctx.config.provider.type}`);
|
|
30846
|
+
console.log(` ${ctx.config.provider.baseUrl}`);
|
|
30847
|
+
} else {
|
|
30848
|
+
console.log(t("repl.provider_current"));
|
|
30849
|
+
for (const p of providers) {
|
|
30850
|
+
const marker = p.active ? pc2.green("* ") : " ";
|
|
30851
|
+
console.log(` ${marker}${p.label} (${pc2.dim(p.type)}) ${pc2.dim(p.baseUrl)}`);
|
|
30852
|
+
}
|
|
30853
|
+
}
|
|
30858
30854
|
return;
|
|
30859
30855
|
}
|
|
30860
30856
|
if (subcmd === "use") {
|
|
@@ -30863,11 +30859,12 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
30863
30859
|
console.log(t("repl.provider_usage"));
|
|
30864
30860
|
return;
|
|
30865
30861
|
}
|
|
30866
|
-
|
|
30867
|
-
|
|
30868
|
-
|
|
30869
|
-
|
|
30870
|
-
|
|
30862
|
+
try {
|
|
30863
|
+
await ctx.agent.setProvider(name);
|
|
30864
|
+
console.log(pc2.green(t("repl.provider_set", { name })));
|
|
30865
|
+
} catch (e) {
|
|
30866
|
+
console.log(pc2.red(e.message));
|
|
30867
|
+
}
|
|
30871
30868
|
return;
|
|
30872
30869
|
}
|
|
30873
30870
|
console.log(t("repl.provider_usage"));
|
|
@@ -31018,70 +31015,6 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
31018
31015
|
}
|
|
31019
31016
|
}
|
|
31020
31017
|
});
|
|
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
|
-
});
|
|
31085
31018
|
}
|
|
31086
31019
|
function registerSessionCommands(ctx) {
|
|
31087
31020
|
if (!ctx.sessionManager)
|
|
@@ -31336,7 +31269,6 @@ var init_repl_commands = __esm(() => {
|
|
|
31336
31269
|
reload: "agent",
|
|
31337
31270
|
wizard: "agent",
|
|
31338
31271
|
sysprompt: "agent",
|
|
31339
|
-
lsp: "agent",
|
|
31340
31272
|
sessions: "session",
|
|
31341
31273
|
new: "session",
|
|
31342
31274
|
resume: "session",
|
|
@@ -31368,9 +31300,10 @@ init_bootstrap();
|
|
|
31368
31300
|
init_config2();
|
|
31369
31301
|
init_setup();
|
|
31370
31302
|
init_i18n();
|
|
31371
|
-
|
|
31303
|
+
init_colors();
|
|
31304
|
+
import { join as join45, dirname as dirname16 } from "path";
|
|
31372
31305
|
import { homedir as homedir16 } from "os";
|
|
31373
|
-
import { existsSync as
|
|
31306
|
+
import { existsSync as existsSync50, readFileSync as readFileSync32 } from "fs";
|
|
31374
31307
|
|
|
31375
31308
|
// src/cli/security-commands.ts
|
|
31376
31309
|
init_bootstrap();
|
|
@@ -32005,15 +31938,15 @@ function createPluginCommand(program2) {
|
|
|
32005
31938
|
}
|
|
32006
31939
|
|
|
32007
31940
|
// src/cli/commands.ts
|
|
32008
|
-
|
|
32009
|
-
import { fileURLToPath as
|
|
31941
|
+
init_presets();
|
|
31942
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
32010
31943
|
function readVersion2() {
|
|
32011
|
-
const here =
|
|
31944
|
+
const here = dirname16(fileURLToPath4(import.meta.url));
|
|
32012
31945
|
const candidates = [join45(here, "..", "..", "package.json"), join45(here, "..", "package.json")];
|
|
32013
31946
|
for (const p of candidates) {
|
|
32014
|
-
if (
|
|
31947
|
+
if (existsSync50(p)) {
|
|
32015
31948
|
try {
|
|
32016
|
-
const raw = JSON.parse(
|
|
31949
|
+
const raw = JSON.parse(readFileSync32(p, "utf8"));
|
|
32017
31950
|
if (raw.version)
|
|
32018
31951
|
return raw.version;
|
|
32019
31952
|
} catch {}
|
|
@@ -32102,8 +32035,8 @@ function createProgram() {
|
|
|
32102
32035
|
model.command("list").description(t("cli.list_models")).action(async () => {
|
|
32103
32036
|
const { config } = await bootstrap();
|
|
32104
32037
|
console.log(t("cli.current_model"), config.model);
|
|
32105
|
-
const {
|
|
32106
|
-
const provider2 =
|
|
32038
|
+
const { createProvider: createProvider2 } = await Promise.resolve().then(() => (init_create(), exports_create));
|
|
32039
|
+
const provider2 = createProvider2(config.provider.type, {
|
|
32107
32040
|
model: config.model,
|
|
32108
32041
|
baseUrl: config.provider.baseUrl,
|
|
32109
32042
|
apiKey: config.provider.apiKey,
|
|
@@ -32183,13 +32116,31 @@ function createProgram() {
|
|
|
32183
32116
|
});
|
|
32184
32117
|
const provider = program2.command("provider").description(t("cli.manage_providers"));
|
|
32185
32118
|
provider.command("list").description(t("cli.list_providers")).action(async () => {
|
|
32186
|
-
const { config } = await bootstrap();
|
|
32119
|
+
const { config, agent } = await bootstrap();
|
|
32120
|
+
const providers = agent.listProviders();
|
|
32121
|
+
if (providers.length > 0) {
|
|
32122
|
+
console.log(t("cli.current_provider"));
|
|
32123
|
+
for (const p of providers) {
|
|
32124
|
+
const marker = p.active ? pc2.green("* ") : " ";
|
|
32125
|
+
console.log(` ${marker}${p.label} (${pc2.dim(p.type)}) ${pc2.dim(p.baseUrl)}`);
|
|
32126
|
+
}
|
|
32127
|
+
return;
|
|
32128
|
+
}
|
|
32187
32129
|
console.log(t("cli.current_provider"), config.provider.type);
|
|
32188
32130
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
32189
32131
|
});
|
|
32190
32132
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
32191
32133
|
const configPath = join45(homedir16(), ".mma", "config.json");
|
|
32192
|
-
const { config } = await bootstrap();
|
|
32134
|
+
const { config, agent } = await bootstrap();
|
|
32135
|
+
if (config.provider.entries && config.provider.entries.length > 0) {
|
|
32136
|
+
try {
|
|
32137
|
+
await agent.setProvider(name);
|
|
32138
|
+
console.log(t("cli.provider_set", { name }));
|
|
32139
|
+
} catch (e) {
|
|
32140
|
+
console.log(pc2.red(e.message));
|
|
32141
|
+
}
|
|
32142
|
+
return;
|
|
32143
|
+
}
|
|
32193
32144
|
config.provider.type = name;
|
|
32194
32145
|
const baseUrl = HOSTED_BASE_URLS[name];
|
|
32195
32146
|
if (baseUrl) {
|
|
@@ -32201,6 +32152,35 @@ function createProgram() {
|
|
|
32201
32152
|
console.log(t("cli.provider_base_hint", { baseUrl }));
|
|
32202
32153
|
}
|
|
32203
32154
|
});
|
|
32155
|
+
provider.command("add").argument("<name>", "Provider type or label").option("--url <url>", "Base URL").option("--key <key>", "API key").description(t("cli.add_provider")).action(async (name, opts) => {
|
|
32156
|
+
const configPath = join45(homedir16(), ".mma", "config.json");
|
|
32157
|
+
const { config } = await bootstrap();
|
|
32158
|
+
const entries = Array.isArray(config.provider.entries) ? config.provider.entries : [];
|
|
32159
|
+
if (entries.length === 0) {
|
|
32160
|
+
entries.push({
|
|
32161
|
+
type: config.provider.type,
|
|
32162
|
+
label: config.provider.type,
|
|
32163
|
+
baseUrl: config.provider.baseUrl,
|
|
32164
|
+
apiKey: config.provider.apiKey
|
|
32165
|
+
});
|
|
32166
|
+
}
|
|
32167
|
+
const baseUrl = opts.url || HOSTED_BASE_URLS[name] || HOSTED_BASE_URLS[`opencode-${name}`] || "";
|
|
32168
|
+
if (!baseUrl) {
|
|
32169
|
+
console.log(pc2.red(t("cli.provider_no_url", { name })));
|
|
32170
|
+
return;
|
|
32171
|
+
}
|
|
32172
|
+
entries.push({
|
|
32173
|
+
type: name,
|
|
32174
|
+
label: name,
|
|
32175
|
+
baseUrl,
|
|
32176
|
+
apiKey: opts.key
|
|
32177
|
+
});
|
|
32178
|
+
config.provider.entries = entries;
|
|
32179
|
+
config.provider.active = config.provider.active || config.provider.type;
|
|
32180
|
+
saveConfig(config, configPath);
|
|
32181
|
+
console.log(pc2.green(t("cli.provider_added", { name })));
|
|
32182
|
+
console.log(t("cli.provider_switch_hint"));
|
|
32183
|
+
});
|
|
32204
32184
|
const session2 = program2.command("session").description(t("cli.manage_sessions"));
|
|
32205
32185
|
session2.command("list").description(t("cli.list_sessions")).action(async () => {
|
|
32206
32186
|
const { sessionManager } = await bootstrap();
|
|
@@ -33003,7 +32983,7 @@ class LineEditor {
|
|
|
33003
32983
|
}
|
|
33004
32984
|
|
|
33005
32985
|
// src/cli/repl.ts
|
|
33006
|
-
import { existsSync as
|
|
32986
|
+
import { existsSync as existsSync53, readFileSync as readFileSync35, writeFileSync as writeFileSync17 } from "fs";
|
|
33007
32987
|
import { join as join48 } from "path";
|
|
33008
32988
|
import { homedir as homedir18 } from "os";
|
|
33009
32989
|
|
|
@@ -33449,8 +33429,9 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
33449
33429
|
`);
|
|
33450
33430
|
}
|
|
33451
33431
|
}
|
|
33452
|
-
toolEnd(_tool, duration, error, ctxDelta, costUsd) {
|
|
33432
|
+
toolEnd(_tool, duration, error, ctxDelta, costUsd, provider, model) {
|
|
33453
33433
|
this.spinner.stop();
|
|
33434
|
+
const prov = provider && model ? `${pc2.dim(`${provider}·${model}`)}` : undefined;
|
|
33454
33435
|
if (!this.rich) {
|
|
33455
33436
|
const parts = [];
|
|
33456
33437
|
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
@@ -33460,6 +33441,8 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
33460
33441
|
if (costUsd !== undefined && costUsd > 0) {
|
|
33461
33442
|
parts.push(`${pc2.dim("cost")} ${pc2.yellow(formatUsd(costUsd))}`);
|
|
33462
33443
|
}
|
|
33444
|
+
if (prov)
|
|
33445
|
+
parts.push(prov);
|
|
33463
33446
|
if (parts.length > 0)
|
|
33464
33447
|
this.out.write(`${parts.join(" ")}
|
|
33465
33448
|
`);
|
|
@@ -33477,6 +33460,9 @@ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
|
33477
33460
|
if (costUsd !== undefined && costUsd > 0) {
|
|
33478
33461
|
footer += ` ${pc2.dim("cost")} ${pc2.yellow(formatUsd(costUsd))}`;
|
|
33479
33462
|
}
|
|
33463
|
+
if (prov) {
|
|
33464
|
+
footer += ` ${pc2.dim("via")} ${prov}`;
|
|
33465
|
+
}
|
|
33480
33466
|
if (this.toolStyle === "inline") {
|
|
33481
33467
|
this.out.write(`${GUTTER}${footer}
|
|
33482
33468
|
`);
|
|
@@ -33576,24 +33562,16 @@ async function probeLspServers(config, baseDir, deps = {}) {
|
|
|
33576
33562
|
await probeClient.probe(server, projectRoot, serverTimeout);
|
|
33577
33563
|
ok.push({ language, ok: true, durationMs: Date.now() - started });
|
|
33578
33564
|
} 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
|
-
});
|
|
33585
33565
|
failed.push({
|
|
33586
33566
|
language,
|
|
33587
33567
|
ok: false,
|
|
33588
|
-
error:
|
|
33568
|
+
error: e instanceof Error ? e.message : String(e),
|
|
33589
33569
|
durationMs: Date.now() - started
|
|
33590
33570
|
});
|
|
33591
33571
|
}
|
|
33592
33572
|
};
|
|
33593
33573
|
for (let i = 0;i < servers.length; i += maxParallel) {
|
|
33594
33574
|
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(", ")}`);
|
|
33597
33575
|
for (const { language } of servers.slice(i)) {
|
|
33598
33576
|
failed.push({ language, ok: false, error: "timeout", durationMs: 0 });
|
|
33599
33577
|
}
|
|
@@ -33612,14 +33590,14 @@ init_config();
|
|
|
33612
33590
|
init_colors();
|
|
33613
33591
|
init_js_identifiers();
|
|
33614
33592
|
init_i18n();
|
|
33615
|
-
import { existsSync as
|
|
33593
|
+
import { existsSync as existsSync52, readFileSync as readFileSync34 } from "fs";
|
|
33616
33594
|
import { join as join47 } from "path";
|
|
33617
33595
|
function readActivePlan(baseDir) {
|
|
33618
33596
|
const p = join47(baseDir, ".mma", "plans", "active.json");
|
|
33619
|
-
if (!
|
|
33597
|
+
if (!existsSync52(p))
|
|
33620
33598
|
return null;
|
|
33621
33599
|
try {
|
|
33622
|
-
const raw =
|
|
33600
|
+
const raw = readFileSync34(p, "utf-8");
|
|
33623
33601
|
if (!raw.trim())
|
|
33624
33602
|
return null;
|
|
33625
33603
|
const parsed = JSON.parse(raw);
|
|
@@ -33798,9 +33776,9 @@ class Repl {
|
|
|
33798
33776
|
this.setupListeners();
|
|
33799
33777
|
}
|
|
33800
33778
|
loadHistory() {
|
|
33801
|
-
if (
|
|
33779
|
+
if (existsSync53(this.historyPath)) {
|
|
33802
33780
|
try {
|
|
33803
|
-
const raw =
|
|
33781
|
+
const raw = readFileSync35(this.historyPath, "utf-8");
|
|
33804
33782
|
this.history = raw.split(`
|
|
33805
33783
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
33806
33784
|
} catch {
|
|
@@ -33892,7 +33870,6 @@ class Repl {
|
|
|
33892
33870
|
this.running = false;
|
|
33893
33871
|
this.saveHistory();
|
|
33894
33872
|
this.agent.shutdown();
|
|
33895
|
-
this.logger?.closeSessionLog();
|
|
33896
33873
|
if (this.exitOnClose)
|
|
33897
33874
|
process.exit(0);
|
|
33898
33875
|
});
|
|
@@ -33901,7 +33878,6 @@ class Repl {
|
|
|
33901
33878
|
this.running = false;
|
|
33902
33879
|
this.saveHistory();
|
|
33903
33880
|
this.agent.shutdown();
|
|
33904
|
-
this.logger?.closeSessionLog();
|
|
33905
33881
|
process.exit(0);
|
|
33906
33882
|
});
|
|
33907
33883
|
}
|
|
@@ -34006,7 +33982,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
34006
33982
|
if (ev.type === "start") {
|
|
34007
33983
|
renderer.toolStart(ev.tool, ev.args, stepContextForTool(this.activePlan, ev.tool, ev.args), ev.icon);
|
|
34008
33984
|
} else {
|
|
34009
|
-
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd);
|
|
33985
|
+
renderer.toolEnd(ev.tool, ev.duration ?? 0, ev.error, ev.ctxDelta, ev.costUsd, ev.provider, ev.model);
|
|
34010
33986
|
if (ev.tool === "plan" || ev.tool === "todo") {
|
|
34011
33987
|
this.refreshActivePlan(renderer);
|
|
34012
33988
|
}
|
|
@@ -34182,7 +34158,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
34182
34158
|
join48(this.baseDir, ".mma", "AGENTS.md"),
|
|
34183
34159
|
join48(this.configDir, "AGENTS.md")
|
|
34184
34160
|
];
|
|
34185
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
34161
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync53(p));
|
|
34186
34162
|
if (foundAgents.length > 0) {
|
|
34187
34163
|
for (const p of foundAgents) {
|
|
34188
34164
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -34248,7 +34224,6 @@ ${t("image.clipboard_empty")}`));
|
|
|
34248
34224
|
this.running = false;
|
|
34249
34225
|
this.saveHistory();
|
|
34250
34226
|
this.agent.shutdown();
|
|
34251
|
-
this.logger?.closeSessionLog();
|
|
34252
34227
|
this.rl.close();
|
|
34253
34228
|
}
|
|
34254
34229
|
}
|
|
@@ -34279,10 +34254,10 @@ init_setup();
|
|
|
34279
34254
|
init_config2();
|
|
34280
34255
|
init_i18n();
|
|
34281
34256
|
init_colors();
|
|
34282
|
-
import { existsSync as
|
|
34283
|
-
import { join as
|
|
34284
|
-
import { homedir as
|
|
34285
|
-
import { fileURLToPath as
|
|
34257
|
+
import { existsSync as existsSync54, readFileSync as readFileSync36 } from "fs";
|
|
34258
|
+
import { join as join49, dirname as dirname18 } from "path";
|
|
34259
|
+
import { homedir as homedir19 } from "os";
|
|
34260
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
34286
34261
|
|
|
34287
34262
|
// src/modules/updater/index.ts
|
|
34288
34263
|
init_checker();
|
|
@@ -34381,61 +34356,14 @@ class UpdaterModule {
|
|
|
34381
34356
|
await this.runOnce();
|
|
34382
34357
|
}
|
|
34383
34358
|
}
|
|
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
|
-
|
|
34431
34359
|
// src/cli/main.ts
|
|
34432
34360
|
function readVersion4() {
|
|
34433
|
-
const here =
|
|
34434
|
-
const candidates = [
|
|
34361
|
+
const here = dirname18(fileURLToPath6(import.meta.url));
|
|
34362
|
+
const candidates = [join49(here, "..", "..", "package.json"), join49(here, "..", "package.json")];
|
|
34435
34363
|
for (const p of candidates) {
|
|
34436
|
-
if (
|
|
34364
|
+
if (existsSync54(p)) {
|
|
34437
34365
|
try {
|
|
34438
|
-
const raw = JSON.parse(
|
|
34366
|
+
const raw = JSON.parse(readFileSync36(p, "utf8"));
|
|
34439
34367
|
if (raw.version)
|
|
34440
34368
|
return raw.version;
|
|
34441
34369
|
} catch {}
|
|
@@ -34460,7 +34388,6 @@ function startAutoUpdate(config) {
|
|
|
34460
34388
|
}
|
|
34461
34389
|
}
|
|
34462
34390
|
async function main() {
|
|
34463
|
-
installCrashHandlers();
|
|
34464
34391
|
const program2 = createProgram();
|
|
34465
34392
|
program2.parse(process.argv);
|
|
34466
34393
|
const cmdNames = new Set(program2.commands.map((c) => c.name()));
|
|
@@ -34520,15 +34447,15 @@ async function main() {
|
|
|
34520
34447
|
await updater?.waitForIdle();
|
|
34521
34448
|
process.exit(exitCode);
|
|
34522
34449
|
} else {
|
|
34523
|
-
const configPath =
|
|
34524
|
-
if (!
|
|
34450
|
+
const configPath = join49(homedir19(), ".mma", "config.json");
|
|
34451
|
+
if (!existsSync54(configPath)) {
|
|
34525
34452
|
console.log(pc2.yellow(`
|
|
34526
34453
|
` + t("cli.first_run") + `
|
|
34527
34454
|
`));
|
|
34528
34455
|
const answers = await runSetup();
|
|
34529
34456
|
const config2 = loadConfig({
|
|
34530
|
-
configDir:
|
|
34531
|
-
projectConfigPath: projectDir ?
|
|
34457
|
+
configDir: join49(homedir19(), ".mma"),
|
|
34458
|
+
projectConfigPath: projectDir ? join49(projectDir, ".mmrc") : join49(process.cwd(), ".mmrc")
|
|
34532
34459
|
});
|
|
34533
34460
|
config2.provider.type = answers.provider;
|
|
34534
34461
|
config2.provider.baseUrl = answers.apiBase;
|