micro-models-agent 0.63.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +148 -1
- package/dist/cli/cache-line.js +30 -0
- package/dist/cli/command-suggest.js +38 -0
- package/dist/cli/commands.js +285 -60
- package/dist/cli/completer.js +16 -16
- package/dist/cli/json-payload.js +32 -0
- package/dist/cli/main.js +165 -77
- package/dist/cli/plugin-commands.js +5 -4
- package/dist/cli/relaunch.js +37 -0
- package/dist/cli/repl-commands.js +441 -307
- package/dist/cli/repl.js +360 -83
- package/dist/cli/run-result.js +12 -6
- package/dist/cli/security-commands.js +64 -60
- package/dist/cli/setup-order.js +57 -0
- package/dist/cli/setup-prompt.js +49 -0
- package/dist/cli/setup.js +52 -48
- package/dist/config/budget.js +48 -0
- package/dist/config/config.js +132 -70
- package/dist/config/defaults.js +37 -11
- package/dist/config/domains.js +9 -50
- package/dist/config/utils.js +56 -0
- package/dist/core/agent/audit-gate.js +49 -0
- package/dist/core/agent/compaction.js +89 -0
- package/dist/core/agent/constants.js +61 -0
- package/dist/core/agent/context-renderer.js +40 -0
- package/dist/core/agent/hallucination-gate.js +87 -0
- package/dist/core/agent/loop-state.js +53 -0
- package/dist/core/agent/prefix-monitor.js +101 -0
- package/dist/core/agent/reasoning-resolver.js +56 -0
- package/dist/core/agent/token-tracker.js +96 -0
- package/dist/core/agent/tool-batch.js +237 -0
- package/dist/core/agent/tool-output.js +62 -0
- package/dist/core/agent-moe.js +214 -69
- package/dist/core/agent.js +506 -546
- package/dist/core/bootstrap.js +297 -98
- package/dist/core/crash-handler.js +2 -1
- package/dist/core/prompt-builder.js +3 -0
- package/dist/core/prompt-overflow.js +307 -0
- package/dist/core/session-logger.js +34 -2
- package/dist/i18n/en.json +7 -4
- package/dist/i18n/ru.json +7 -4
- package/dist/index.js +5 -1
- package/dist/llm/cache-usage.js +76 -0
- package/dist/llm/image-utils.js +20 -16
- package/dist/llm/llm-errors.js +41 -0
- package/dist/llm/model-loader.js +30 -0
- package/dist/llm/openai-compat.js +287 -101
- package/dist/llm/orchestrator.js +140 -68
- package/dist/llm/provider-budget.js +68 -0
- package/dist/llm/provider.js +0 -1
- package/dist/llm/stream-state.js +26 -0
- package/dist/llm/token-counter.js +28 -0
- package/dist/logger/app-logger.js +12 -15
- package/dist/main.js +1606 -800
- package/dist/migration/detect.js +3 -1
- package/dist/modules/browser/actions.js +0 -3
- package/dist/modules/browser/bridge-client.js +2 -0
- package/dist/modules/browser/driver.js +46 -4
- package/dist/modules/certification/cli.js +85 -42
- package/dist/modules/certification/loader.js +15 -1
- package/dist/modules/certification/manifest.js +126 -15
- package/dist/modules/certification/runner.js +4 -26
- package/dist/modules/certification/scenarios.js +184 -5
- package/dist/modules/certification/syntax-scenarios.js +51 -0
- package/dist/modules/context/chunk-query.js +25 -5
- package/dist/modules/context/fact-extractor.js +6 -2
- package/dist/modules/context/manager.js +23 -7
- package/dist/modules/execution/audit-runners.js +7 -1
- package/dist/modules/execution/auditor.js +3 -3
- package/dist/modules/execution/execution-plugin.js +22 -15
- package/dist/modules/execution/input-from.js +46 -0
- package/dist/modules/execution/module.js +107 -18
- package/dist/modules/execution/moe-executor.js +166 -54
- package/dist/modules/execution/plan-actions.js +524 -0
- package/dist/modules/execution/plan-steps.js +23 -0
- package/dist/modules/execution/plan-store.js +15 -3
- package/dist/modules/execution/plan-tool.js +6 -488
- package/dist/modules/execution/plan-validator.js +24 -0
- package/dist/modules/execution/stuck-detector.js +3 -18
- package/dist/modules/execution/tracker.js +14 -5
- package/dist/modules/execution/transient-error.js +30 -0
- package/dist/modules/execution/verifier.js +94 -7
- package/dist/modules/execution/windows-commands.js +11 -0
- package/dist/modules/hallucination/confidence.js +36 -23
- package/dist/modules/hallucination/consistency.js +3 -0
- package/dist/modules/hallucination/detector.js +8 -3
- package/dist/modules/hallucination/factual.js +26 -7
- package/dist/modules/hallucination/llm-judge.js +12 -2
- package/dist/modules/indexer/map-command.js +35 -0
- package/dist/modules/indexer/map-select.js +87 -0
- package/dist/modules/indexer/module.js +34 -22
- package/dist/modules/indexer/symbols.js +189 -0
- package/dist/modules/indexer/walker.js +96 -42
- package/dist/modules/lsp/check-tool.js +2 -1
- package/dist/modules/lsp/client.js +49 -32
- package/dist/modules/lsp/config.js +55 -2
- package/dist/modules/lsp/module.js +38 -5
- package/dist/modules/lsp/probe.js +4 -3
- package/dist/modules/lsp/project-root.js +41 -1
- package/dist/modules/lsp/startup-check.js +12 -4
- package/dist/modules/mcp/client.js +153 -104
- package/dist/modules/mcp/module.js +165 -41
- package/dist/modules/memory/module.js +4 -3
- package/dist/modules/plugins/builtin/lint-on-write.js +36 -6
- package/dist/modules/plugins/manager.js +47 -84
- package/dist/modules/pricing/index.js +17 -7
- package/dist/modules/pricing/prices.js +30 -12
- package/dist/modules/processes/index.js +1 -0
- package/dist/modules/processes/kill-tree.js +56 -0
- package/dist/modules/processes/registry.js +2 -54
- package/dist/modules/providers/cache.js +23 -0
- package/dist/modules/providers/factory.js +28 -0
- package/dist/modules/providers/fallback.js +7 -5
- package/dist/modules/providers/health.js +2 -1
- package/dist/modules/providers/index.js +1 -0
- package/dist/modules/providers/manager.js +17 -2
- package/dist/modules/providers/presets.js +79 -6
- package/dist/modules/reasoning/policy.js +40 -0
- package/dist/modules/reasoning/probe.js +111 -0
- package/dist/modules/security/audit-notifier.js +42 -27
- package/dist/modules/security/command-validator.js +25 -20
- package/dist/modules/security/encryption.js +6 -12
- package/dist/modules/security/network-validator.js +76 -5
- package/dist/modules/security/path-validator.js +77 -34
- package/dist/modules/security/rate-limiter.js +11 -0
- package/dist/modules/security/security-policies.js +1 -1
- package/dist/modules/security/session-encryption.js +13 -2
- package/dist/modules/security/session-isolation.js +2 -9
- package/dist/modules/session/manager.js +11 -0
- package/dist/modules/session/module.js +11 -3
- package/dist/modules/session/store.js +41 -5
- package/dist/modules/skills/loader.js +7 -1
- package/dist/modules/skills/module.js +2 -1
- package/dist/modules/updater/changelog-reader.js +94 -0
- package/dist/modules/updater/dev-detect.js +17 -0
- package/dist/modules/updater/index.js +1 -0
- package/dist/modules/updater/module.js +14 -3
- package/dist/output/bus.js +32 -0
- package/dist/output/channel.js +233 -0
- package/dist/output/format.js +14 -0
- package/dist/output/index.js +7 -0
- package/dist/output/json-sink.js +22 -0
- package/dist/output/machine.js +8 -0
- package/dist/output/session-sink.js +27 -0
- package/dist/output/types.js +1 -0
- package/dist/tools/approve.js +6 -2
- package/dist/tools/attach-image.js +11 -11
- package/dist/tools/auto-fixer.js +198 -0
- package/dist/tools/bash.js +142 -89
- package/dist/tools/chunk-query.js +10 -6
- package/dist/tools/download-file.js +1 -1
- package/dist/tools/edit-file.js +20 -2
- package/dist/tools/executor.js +54 -9
- package/dist/tools/glob-tool.js +7 -0
- package/dist/tools/grep-tool.js +15 -1
- package/dist/tools/index.js +3 -1
- package/dist/tools/list-dir.js +3 -1
- package/dist/tools/load-skill.js +2 -1
- package/dist/tools/mcp-call.js +1 -1
- package/dist/tools/move-file.js +5 -4
- package/dist/tools/path-utils.js +7 -0
- package/dist/tools/pipeline-run.js +1 -1
- package/dist/tools/prompt-io.js +28 -0
- package/dist/tools/question.js +12 -12
- package/dist/tools/scope-request.js +91 -0
- package/dist/tools/session-info.js +44 -0
- package/dist/tools/set-thinking.js +71 -0
- package/dist/tools/subagent.js +50 -9
- package/dist/tools/syntax-validator.js +177 -0
- package/dist/tools/user-input.js +16 -9
- package/dist/tools/write-file.js +17 -1
- package/dist/ui/diff.js +10 -0
- package/dist/ui/line-editor.js +179 -26
- package/dist/ui/line-math.js +20 -3
- package/dist/ui/md-formatter.js +100 -10
- package/dist/ui/output.js +5 -4
- package/dist/ui/plan-view.js +2 -7
- package/dist/ui/renderer.js +89 -85
- package/dist/ui/spinner.js +14 -4
- package/dist/utils/error.js +4 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/retry.js +17 -0
- package/dist/utils/sleep.js +23 -0
- package/dist/utils/truncate.js +9 -0
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2790,6 +2790,7 @@ Fix the error and re-edit the file (a clean write clears the failure), or mark t
|
|
|
2790
2790
|
"cli.show_details": "Show session details",
|
|
2791
2791
|
"cli.delete_session": "Delete a session",
|
|
2792
2792
|
"cli.first_run": "First run detected. Running setup wizard...",
|
|
2793
|
+
"cli.setup_saved_restart": "Settings saved. Restarting with the new configuration...",
|
|
2793
2794
|
"cli.unknown_cmd": "Unknown command: {name}.",
|
|
2794
2795
|
"cli.unknown_command": 'Unknown command "{input}". Did you mean "{suggestion}"?',
|
|
2795
2796
|
"cli.help_hint": "Type /help for available commands.",
|
|
@@ -2892,6 +2893,8 @@ Available commands:`,
|
|
|
2892
2893
|
"repl.skill_usage": "Usage: /skill [list|loaded|load|unload|search]",
|
|
2893
2894
|
"repl.agent": "Agent: ",
|
|
2894
2895
|
"repl.you": "You: ",
|
|
2896
|
+
"repl.you_reasoning": "You [{level}]: ",
|
|
2897
|
+
"repl.you_reasoning_cont": "You [{level}]… ",
|
|
2895
2898
|
"repl.interrupt": "Interrupted (Esc)",
|
|
2896
2899
|
"repl.title": "MMA REPL v{version}",
|
|
2897
2900
|
"repl.model": "Model:",
|
|
@@ -2965,6 +2968,8 @@ Excluded blocks: {count}`,
|
|
|
2965
2968
|
Select provider type:`,
|
|
2966
2969
|
"setup.select_provider_num": `
|
|
2967
2970
|
Select provider (1-{max})`,
|
|
2971
|
+
"setup.select_language_num": `
|
|
2972
|
+
Select language (1-{max})`,
|
|
2968
2973
|
"setup.scanning": " Scanning local LLM servers...",
|
|
2969
2974
|
"setup.found_servers": " Found {count} server(s):",
|
|
2970
2975
|
"setup.no_servers": " No local servers found. Enter URL manually.",
|
|
@@ -2995,8 +3000,6 @@ Excluded blocks: {count}`,
|
|
|
2995
3000
|
"setup.scanning_spinner": "Scanning local LLM servers…",
|
|
2996
3001
|
"setup.fetching_spinner": "Fetching model list…",
|
|
2997
3002
|
"setup.testing_spinner": 'Testing chat with "{model}"…',
|
|
2998
|
-
"setup.summary_setting": "Setting",
|
|
2999
|
-
"setup.summary_value": "Value",
|
|
3000
3003
|
"setup.security_header": `
|
|
3001
3004
|
--- Security ---`,
|
|
3002
3005
|
"setup.security_status_off": " Security: OFF (default — all commands allowed)",
|
|
@@ -3057,6 +3060,7 @@ Apply a matching solution from these results. If none is relevant — do NOT rep
|
|
|
3057
3060
|
"exec.error_search_failed": 'Web search returned nothing for "{query}".',
|
|
3058
3061
|
"exec.error_search_no_query": "Error output is not meaningful — skipping the web search.",
|
|
3059
3062
|
"exec.npm_exec_hint": '"could not determine executable to run" — no "bin" for that package/script. Use "npm run <script>" (script must exist in package.json) or "bunx <pkg>" for a package that declares a bin.',
|
|
3063
|
+
"exec.interactive_hint": "the command needed interactive input but the shell has no TTY (prompt aborted). Re-run it non-interactively — pass every required flag/argument (e.g. `bun create vite <name> --template react-ts` instead of a bare interactive scaffold).",
|
|
3060
3064
|
"exec.hidden_tool_hint": '"{tool}" is not a shell command — it is an MMA tool that is currently hidden. Call the enable_tools tool with tags ["shell"] to unlock it; it becomes available on the next iteration.',
|
|
3061
3065
|
"exec.task_reminder": "Task: {task}. Continue making progress — do not repeat failed actions.",
|
|
3062
3066
|
"hall.max_retries_exhausted": "Model returned empty or insufficient responses after multiple retries",
|
|
@@ -3240,9 +3244,9 @@ Apply a matching solution from these results. If none is relevant — do NOT rep
|
|
|
3240
3244
|
"prompt.overflow.hint_needed": "the prompt needs ~{needed} system tokens (current budget: {window} × {fraction} = {budget})",
|
|
3241
3245
|
"prompt.overflow.hint_window": "raise contextWindow to at least {required} (standard size {recommended}) — {how}",
|
|
3242
3246
|
"prompt.overflow.hint_fraction": "or keep the window and raise contextBudget.systemPrompt to ~{fraction} (run: mma context --system {fraction})",
|
|
3243
|
-
"prompt.overflow.exceeded": 'Prompt overflow:
|
|
3247
|
+
"prompt.overflow.exceeded": 'Prompt overflow: the system prompt needs ~{needed} tok (budget {budget} tok); "{label}" ({original} tok) was {mode} to {resolved} tok. To fit everything fully, {hint}.',
|
|
3244
3248
|
"prompt.overflow.failed": "Prompt overflow resolution failed: {error} — oversized blocks will be dropped.",
|
|
3245
|
-
"prompt.overflow.startup": "Startup check: {
|
|
3249
|
+
"prompt.overflow.startup": "Startup check: the system prompt needs ~{needed} tok (budget: {budget} tok); {block} ({original} tok) will be summarized/truncated before the first run. To include everything fully, {hint}.",
|
|
3246
3250
|
"tool.session_info.no_active": "No active session",
|
|
3247
3251
|
"tool.session_info.result": `Session: "{name}" ({id})
|
|
3248
3252
|
Model: {model}
|
|
@@ -3622,6 +3626,7 @@ var init_ru = __esm(() => {
|
|
|
3622
3626
|
"cli.show_details": "Показать детали сессии",
|
|
3623
3627
|
"cli.delete_session": "Удалить сессию",
|
|
3624
3628
|
"cli.first_run": "Первый запуск. Запускаем мастер настройки...",
|
|
3629
|
+
"cli.setup_saved_restart": "Настройки сохранены. Перезапуск с новой конфигурацией...",
|
|
3625
3630
|
"cli.unknown_cmd": "Неизвестная команда: {name}.",
|
|
3626
3631
|
"cli.unknown_command": 'Неизвестная команда "{input}". Возможно, вы имели в виду "{suggestion}"?',
|
|
3627
3632
|
"cli.help_hint": "Введите /help для списка команд.",
|
|
@@ -3724,6 +3729,8 @@ var init_ru = __esm(() => {
|
|
|
3724
3729
|
"repl.skill_usage": "Использование: /skill [list|loaded|load|unload|search]",
|
|
3725
3730
|
"repl.agent": "Агент: ",
|
|
3726
3731
|
"repl.you": "Вы: ",
|
|
3732
|
+
"repl.you_reasoning": "Вы [{level}]: ",
|
|
3733
|
+
"repl.you_reasoning_cont": "Вы [{level}]… ",
|
|
3727
3734
|
"repl.interrupt": "Прервано (Esc)",
|
|
3728
3735
|
"repl.title": "MMA REPL v{version}",
|
|
3729
3736
|
"repl.model": "Модель:",
|
|
@@ -3801,6 +3808,8 @@ var init_ru = __esm(() => {
|
|
|
3801
3808
|
Выберите тип провайдера:`,
|
|
3802
3809
|
"setup.select_provider_num": `
|
|
3803
3810
|
Выберите провайдер (1-{max})`,
|
|
3811
|
+
"setup.select_language_num": `
|
|
3812
|
+
Выберите язык (1-{max})`,
|
|
3804
3813
|
"setup.scanning": " Сканирование локальных LLM-серверов...",
|
|
3805
3814
|
"setup.found_servers": " Найдено серверов: {count}",
|
|
3806
3815
|
"setup.no_servers": " Локальные серверы не найдены. Введите URL вручную.",
|
|
@@ -3831,8 +3840,6 @@ var init_ru = __esm(() => {
|
|
|
3831
3840
|
"setup.scanning_spinner": "Сканирование локальных LLM-серверов…",
|
|
3832
3841
|
"setup.fetching_spinner": "Загрузка списка моделей…",
|
|
3833
3842
|
"setup.testing_spinner": 'Проверка чата с "{model}"…',
|
|
3834
|
-
"setup.summary_setting": "Параметр",
|
|
3835
|
-
"setup.summary_value": "Значение",
|
|
3836
3843
|
"setup.security_header": `
|
|
3837
3844
|
--- Безопасность ---`,
|
|
3838
3845
|
"setup.security_status_off": " Безопасность: ВЫКЛ (по умолчанию — все команды разрешены)",
|
|
@@ -3893,6 +3900,7 @@ var init_ru = __esm(() => {
|
|
|
3893
3900
|
"exec.error_search_failed": 'Поиск в интернете для "{query}" ничего не дал.',
|
|
3894
3901
|
"exec.error_search_no_query": "Текст ошибки незначимый — поиск в интернете пропущен.",
|
|
3895
3902
|
"exec.npm_exec_hint": '"could not determine executable to run" — у пакета/скрипта нет "bin". Используй "npm run <script>" (скрипт должен быть в package.json) или "bunx <pkg>" для пакета с объявленным bin.',
|
|
3903
|
+
"exec.interactive_hint": "команде нужен интерактивный ввод, но у шелла нет TTY (запрос отменён). Запусти её неинтерактивно — передай все нужные флаги/аргументы (например, `bun create vite <name> --template react-ts` вместо голого интерактивного скаффолда).",
|
|
3896
3904
|
"exec.hidden_tool_hint": '"{tool}" — не команда оболочки, это инструмент MMA, который сейчас скрыт. Вызови тул enable_tools с tags ["shell"], чтобы включить его; он станет доступен на следующей итерации.',
|
|
3897
3905
|
"exec.task_reminder": "Задача: {task}. Продолжай работу — не повторяй неудачные действия.",
|
|
3898
3906
|
"hall.max_retries_exhausted": "Модель вернула пустой или недостаточный ответ после нескольких попыток",
|
|
@@ -4079,9 +4087,9 @@ var init_ru = __esm(() => {
|
|
|
4079
4087
|
"prompt.overflow.hint_needed": "промпту нужно ~{needed} токенов системного бюджета (сейчас: {window} × {fraction} = {budget})",
|
|
4080
4088
|
"prompt.overflow.hint_window": "подними contextWindow минимум до {required} (стандартный размер {recommended}) — {how}",
|
|
4081
4089
|
"prompt.overflow.hint_fraction": "или оставь окно и подними contextBudget.systemPrompt до ~{fraction} (выполни: mma context --system {fraction})",
|
|
4082
|
-
"prompt.overflow.exceeded": 'Промпт переполнен:
|
|
4090
|
+
"prompt.overflow.exceeded": 'Промпт переполнен: системному промпту нужно ~{needed} токенов (бюджет {budget} токенов); "{label}" ({original} токенов) было {mode} до {resolved} токенов. Чтобы включить всё полностью, {hint}.',
|
|
4083
4091
|
"prompt.overflow.failed": "Не удалось разрешить переполнение промпта: {error} — слишком большие блоки будут отброшены.",
|
|
4084
|
-
"prompt.overflow.startup": "Проверка при старте: {
|
|
4092
|
+
"prompt.overflow.startup": "Проверка при старте: системному промпту нужно ~{needed} токенов (бюджет: {budget} токенов); {block} ({original} токенов) будет суммаризован/обрезан перед первым запуском. Чтобы включить всё полностью, {hint}.",
|
|
4085
4093
|
"tool.session_info.no_active": "Нет активной сессии",
|
|
4086
4094
|
"tool.session_info.result": `Сессия: "{name}" ({id})
|
|
4087
4095
|
Модель: {model}
|
|
@@ -4513,6 +4521,398 @@ var init_encryption = __esm(() => {
|
|
|
4513
4521
|
"key"
|
|
4514
4522
|
];
|
|
4515
4523
|
});
|
|
4524
|
+
// src/output/bus.ts
|
|
4525
|
+
class OutputBus {
|
|
4526
|
+
seq = 0;
|
|
4527
|
+
subs = new Set;
|
|
4528
|
+
subscribe(fn) {
|
|
4529
|
+
this.subs.add(fn);
|
|
4530
|
+
return () => this.subs.delete(fn);
|
|
4531
|
+
}
|
|
4532
|
+
emit(ev) {
|
|
4533
|
+
const full = { ...ev, id: ++this.seq, ts: Date.now() };
|
|
4534
|
+
for (const fn of [...this.subs]) {
|
|
4535
|
+
try {
|
|
4536
|
+
fn(full);
|
|
4537
|
+
} catch {}
|
|
4538
|
+
}
|
|
4539
|
+
return full;
|
|
4540
|
+
}
|
|
4541
|
+
log(level, source, text, data) {
|
|
4542
|
+
return this.emit({ level, source, kind: "log", text, data });
|
|
4543
|
+
}
|
|
4544
|
+
reset() {
|
|
4545
|
+
this.subs.clear();
|
|
4546
|
+
this.seq = 0;
|
|
4547
|
+
}
|
|
4548
|
+
}
|
|
4549
|
+
var defaultOutputBus;
|
|
4550
|
+
var init_bus = __esm(() => {
|
|
4551
|
+
defaultOutputBus = new OutputBus;
|
|
4552
|
+
});
|
|
4553
|
+
|
|
4554
|
+
// node_modules/picocolors/picocolors.js
|
|
4555
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
4556
|
+
var p = process || {};
|
|
4557
|
+
var argv = p.argv || [];
|
|
4558
|
+
var env = p.env || {};
|
|
4559
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
4560
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
4561
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
4562
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
4563
|
+
};
|
|
4564
|
+
var replaceClose = (string, close, replace, index) => {
|
|
4565
|
+
let result = "", cursor = 0;
|
|
4566
|
+
do {
|
|
4567
|
+
result += string.substring(cursor, index) + replace;
|
|
4568
|
+
cursor = index + close.length;
|
|
4569
|
+
index = string.indexOf(close, cursor);
|
|
4570
|
+
} while (~index);
|
|
4571
|
+
return result + string.substring(cursor);
|
|
4572
|
+
};
|
|
4573
|
+
var createColors = (enabled = isColorSupported) => {
|
|
4574
|
+
let f = enabled ? formatter : () => String;
|
|
4575
|
+
return {
|
|
4576
|
+
isColorSupported: enabled,
|
|
4577
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
4578
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
4579
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
4580
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
4581
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
4582
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
4583
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
4584
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
4585
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
4586
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
4587
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
4588
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
4589
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
4590
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
4591
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
4592
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
4593
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
4594
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
4595
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
4596
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
4597
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
4598
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
4599
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
4600
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
4601
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
4602
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
4603
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
4604
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
4605
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
4606
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
4607
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
4608
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
4609
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
4610
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
4611
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
4612
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
4613
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
4614
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
4615
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
4616
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
4617
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
4618
|
+
};
|
|
4619
|
+
};
|
|
4620
|
+
module.exports = createColors();
|
|
4621
|
+
module.exports.createColors = createColors;
|
|
4622
|
+
});
|
|
4623
|
+
|
|
4624
|
+
// src/output/format.ts
|
|
4625
|
+
function formatEventLine(ev, color) {
|
|
4626
|
+
const prefix = ev.source ? ` [${ev.source}]` : "";
|
|
4627
|
+
const line = `[${ev.level.toUpperCase()}]${prefix} ${new Date(ev.ts).toISOString()} — ${ev.text}`;
|
|
4628
|
+
return color ? LEVEL_COLORS[ev.level](line) : line;
|
|
4629
|
+
}
|
|
4630
|
+
var import_picocolors, colored, LEVEL_COLORS;
|
|
4631
|
+
var init_format = __esm(() => {
|
|
4632
|
+
import_picocolors = __toESM(require_picocolors(), 1);
|
|
4633
|
+
colored = import_picocolors.createColors(true);
|
|
4634
|
+
LEVEL_COLORS = {
|
|
4635
|
+
debug: (s) => colored.dim(s),
|
|
4636
|
+
info: (s) => s,
|
|
4637
|
+
warn: (s) => colored.yellow(s),
|
|
4638
|
+
error: (s) => colored.red(s)
|
|
4639
|
+
};
|
|
4640
|
+
});
|
|
4641
|
+
|
|
4642
|
+
// src/output/json-sink.ts
|
|
4643
|
+
class JsonOutputSink {
|
|
4644
|
+
events = [];
|
|
4645
|
+
unsub;
|
|
4646
|
+
constructor(bus) {
|
|
4647
|
+
this.unsub = bus.subscribe((ev) => {
|
|
4648
|
+
this.events.push(ev);
|
|
4649
|
+
});
|
|
4650
|
+
}
|
|
4651
|
+
diagnostics() {
|
|
4652
|
+
return this.events.filter((e) => e.level === "warn" || e.level === "error").map((e) => ({ level: e.level, source: e.source, text: e.text }));
|
|
4653
|
+
}
|
|
4654
|
+
dispose() {
|
|
4655
|
+
this.unsub();
|
|
4656
|
+
}
|
|
4657
|
+
}
|
|
4658
|
+
|
|
4659
|
+
// src/output/session-sink.ts
|
|
4660
|
+
class SessionOutputSink {
|
|
4661
|
+
session;
|
|
4662
|
+
unsub;
|
|
4663
|
+
constructor(bus, session) {
|
|
4664
|
+
this.session = session;
|
|
4665
|
+
this.unsub = bus.subscribe((ev) => {
|
|
4666
|
+
if (ev.data?.persist !== true)
|
|
4667
|
+
return;
|
|
4668
|
+
this.session.appendLog({
|
|
4669
|
+
ts: new Date(ev.ts).toISOString(),
|
|
4670
|
+
type: "output",
|
|
4671
|
+
level: ev.level,
|
|
4672
|
+
source: ev.source,
|
|
4673
|
+
content: ev.text
|
|
4674
|
+
});
|
|
4675
|
+
});
|
|
4676
|
+
}
|
|
4677
|
+
dispose() {
|
|
4678
|
+
this.unsub();
|
|
4679
|
+
}
|
|
4680
|
+
}
|
|
4681
|
+
|
|
4682
|
+
// src/output/channel.ts
|
|
4683
|
+
class OutputChannel {
|
|
4684
|
+
bus;
|
|
4685
|
+
out;
|
|
4686
|
+
err;
|
|
4687
|
+
color;
|
|
4688
|
+
mode = "idle";
|
|
4689
|
+
modeBeforeQuiet = "idle";
|
|
4690
|
+
modeBeforeModal = "idle";
|
|
4691
|
+
modalDepth = 0;
|
|
4692
|
+
sink = null;
|
|
4693
|
+
queue = [];
|
|
4694
|
+
pending = null;
|
|
4695
|
+
partialOpen = false;
|
|
4696
|
+
blockLines = null;
|
|
4697
|
+
blockFlushScheduled = false;
|
|
4698
|
+
unsub;
|
|
4699
|
+
constructor(bus = defaultOutputBus, opts = {}) {
|
|
4700
|
+
this.bus = bus;
|
|
4701
|
+
this.out = opts.out ?? process.stdout;
|
|
4702
|
+
this.err = opts.err ?? process.stderr;
|
|
4703
|
+
const outTTY = this.out.isTTY === true;
|
|
4704
|
+
this.color = opts.color ?? (!process.env.NO_COLOR && !process.env.CI && outTTY);
|
|
4705
|
+
this.unsub = this.bus.subscribe((ev) => this.onEvent(ev));
|
|
4706
|
+
}
|
|
4707
|
+
dispose() {
|
|
4708
|
+
this.flushBlocks();
|
|
4709
|
+
this.unsub();
|
|
4710
|
+
this.queue = [];
|
|
4711
|
+
this.pending = null;
|
|
4712
|
+
this.partialOpen = false;
|
|
4713
|
+
this.sink = null;
|
|
4714
|
+
this.mode = "idle";
|
|
4715
|
+
}
|
|
4716
|
+
attachPrompt(sink) {
|
|
4717
|
+
this.sink = sink;
|
|
4718
|
+
}
|
|
4719
|
+
getMode() {
|
|
4720
|
+
return this.mode;
|
|
4721
|
+
}
|
|
4722
|
+
beginStreaming() {
|
|
4723
|
+
if (this.mode === "quiet")
|
|
4724
|
+
return;
|
|
4725
|
+
this.flushBlocks();
|
|
4726
|
+
this.flushPendingAsBlock();
|
|
4727
|
+
this.mode = "streaming";
|
|
4728
|
+
}
|
|
4729
|
+
endStreaming() {
|
|
4730
|
+
if (this.mode === "quiet")
|
|
4731
|
+
return;
|
|
4732
|
+
this.closePartial();
|
|
4733
|
+
this.mode = "idle";
|
|
4734
|
+
}
|
|
4735
|
+
beginModal() {
|
|
4736
|
+
this.flushBlocks();
|
|
4737
|
+
this.flushPendingAsBlock();
|
|
4738
|
+
if (this.mode === "quiet")
|
|
4739
|
+
return;
|
|
4740
|
+
if (this.modalDepth === 0)
|
|
4741
|
+
this.modeBeforeModal = this.mode;
|
|
4742
|
+
this.modalDepth++;
|
|
4743
|
+
this.mode = "modal";
|
|
4744
|
+
}
|
|
4745
|
+
endModal() {
|
|
4746
|
+
if (this.modalDepth > 0)
|
|
4747
|
+
this.modalDepth--;
|
|
4748
|
+
if (this.mode === "modal" && this.modalDepth === 0)
|
|
4749
|
+
this.mode = this.modeBeforeModal;
|
|
4750
|
+
const q = this.queue;
|
|
4751
|
+
this.queue = [];
|
|
4752
|
+
for (const ev of q)
|
|
4753
|
+
this.onEvent(ev);
|
|
4754
|
+
}
|
|
4755
|
+
setQuiet(quiet) {
|
|
4756
|
+
this.flushBlocks();
|
|
4757
|
+
if (quiet) {
|
|
4758
|
+
if (this.mode !== "quiet") {
|
|
4759
|
+
this.modeBeforeQuiet = this.mode;
|
|
4760
|
+
this.mode = "quiet";
|
|
4761
|
+
}
|
|
4762
|
+
} else if (this.mode === "quiet") {
|
|
4763
|
+
this.mode = this.modeBeforeQuiet;
|
|
4764
|
+
}
|
|
4765
|
+
}
|
|
4766
|
+
writeRaw(text, stream = "stdout") {
|
|
4767
|
+
this.flushBlocks();
|
|
4768
|
+
if (this.mode === "modal" || this.mode === "quiet")
|
|
4769
|
+
return;
|
|
4770
|
+
if (this.mode === "idle" && this.sink?.isActive() && stream === "stdout") {
|
|
4771
|
+
const prev = this.pending?.stream === "stdout" ? this.pending.text : "";
|
|
4772
|
+
this.pending = { stream, text: prev + text };
|
|
4773
|
+
this.drainPending();
|
|
4774
|
+
return;
|
|
4775
|
+
}
|
|
4776
|
+
if (stream === "stdout")
|
|
4777
|
+
this.partialOpen = !text.endsWith(`
|
|
4778
|
+
`);
|
|
4779
|
+
(stream === "stderr" ? this.err : this.out).write(text);
|
|
4780
|
+
}
|
|
4781
|
+
writeLine(text, stream = "stdout") {
|
|
4782
|
+
this.bus.emit({ level: "info", source: "", kind: "block", text, stream });
|
|
4783
|
+
}
|
|
4784
|
+
clearScreen() {
|
|
4785
|
+
this.flushBlocks();
|
|
4786
|
+
this.flushPendingAsBlock();
|
|
4787
|
+
this.partialOpen = false;
|
|
4788
|
+
if (this.mode === "quiet")
|
|
4789
|
+
return;
|
|
4790
|
+
if (this.sink?.isActive() && this.sink.clearScreen) {
|
|
4791
|
+
this.sink.clearScreen();
|
|
4792
|
+
return;
|
|
4793
|
+
}
|
|
4794
|
+
this.out.write("\x1B[2J\x1B[H");
|
|
4795
|
+
}
|
|
4796
|
+
writeOverlay(text) {
|
|
4797
|
+
if (this.mode === "modal" || this.mode === "quiet")
|
|
4798
|
+
return;
|
|
4799
|
+
if (this.mode === "idle" && this.sink?.isActive())
|
|
4800
|
+
return;
|
|
4801
|
+
this.err.write(text);
|
|
4802
|
+
}
|
|
4803
|
+
onEvent(ev) {
|
|
4804
|
+
if (this.mode === "quiet")
|
|
4805
|
+
return;
|
|
4806
|
+
if (this.mode === "modal") {
|
|
4807
|
+
this.queue.push(ev);
|
|
4808
|
+
return;
|
|
4809
|
+
}
|
|
4810
|
+
if (ev.kind === "raw") {
|
|
4811
|
+
this.writeRaw(ev.text, ev.stream);
|
|
4812
|
+
return;
|
|
4813
|
+
}
|
|
4814
|
+
const stream = ev.stream ?? "stdout";
|
|
4815
|
+
const line = ev.kind === "block" ? ev.text : formatEventLine(ev, this.color);
|
|
4816
|
+
if (this.mode === "idle" && this.sink?.isActive()) {
|
|
4817
|
+
if (this.blockLines === null)
|
|
4818
|
+
this.blockLines = [];
|
|
4819
|
+
this.blockLines.push(line);
|
|
4820
|
+
if (!this.blockFlushScheduled) {
|
|
4821
|
+
this.blockFlushScheduled = true;
|
|
4822
|
+
queueMicrotask(() => this.flushBlocks());
|
|
4823
|
+
}
|
|
4824
|
+
return;
|
|
4825
|
+
}
|
|
4826
|
+
this.flushBlocks();
|
|
4827
|
+
if (this.mode === "streaming")
|
|
4828
|
+
this.closePartial();
|
|
4829
|
+
(stream === "stderr" ? this.err : this.out).write(`${line}
|
|
4830
|
+
`);
|
|
4831
|
+
}
|
|
4832
|
+
flushBlocks() {
|
|
4833
|
+
this.blockFlushScheduled = false;
|
|
4834
|
+
const lines = this.blockLines;
|
|
4835
|
+
this.blockLines = null;
|
|
4836
|
+
if (!lines || lines.length === 0)
|
|
4837
|
+
return;
|
|
4838
|
+
const text = lines.join(`
|
|
4839
|
+
`);
|
|
4840
|
+
if (this.sink?.isActive()) {
|
|
4841
|
+
this.sink.printAbove(text);
|
|
4842
|
+
} else {
|
|
4843
|
+
this.out.write(`${text}
|
|
4844
|
+
`);
|
|
4845
|
+
}
|
|
4846
|
+
}
|
|
4847
|
+
closePartial() {
|
|
4848
|
+
if (this.partialOpen) {
|
|
4849
|
+
this.out.write(`
|
|
4850
|
+
`);
|
|
4851
|
+
this.partialOpen = false;
|
|
4852
|
+
}
|
|
4853
|
+
}
|
|
4854
|
+
drainPending() {
|
|
4855
|
+
if (!this.pending)
|
|
4856
|
+
return;
|
|
4857
|
+
const { stream, text } = this.pending;
|
|
4858
|
+
const idx = text.lastIndexOf(`
|
|
4859
|
+
`);
|
|
4860
|
+
if (idx < 0)
|
|
4861
|
+
return;
|
|
4862
|
+
const head = text.slice(0, idx + 1);
|
|
4863
|
+
this.pending = { stream, text: text.slice(idx + 1) };
|
|
4864
|
+
const lines = head.replace(/\n$/, "").split(`
|
|
4865
|
+
`);
|
|
4866
|
+
if (this.sink?.isActive())
|
|
4867
|
+
this.sink.printAbove(lines.join(`
|
|
4868
|
+
`));
|
|
4869
|
+
else
|
|
4870
|
+
this.out.write(head);
|
|
4871
|
+
}
|
|
4872
|
+
flushPendingAsBlock() {
|
|
4873
|
+
this.flushBlocks();
|
|
4874
|
+
if (!this.pending)
|
|
4875
|
+
return;
|
|
4876
|
+
const text = this.pending.text;
|
|
4877
|
+
const { stream } = this.pending;
|
|
4878
|
+
this.pending = null;
|
|
4879
|
+
if (this.sink?.isActive()) {
|
|
4880
|
+
this.sink.printAbove(text);
|
|
4881
|
+
this.partialOpen = false;
|
|
4882
|
+
} else {
|
|
4883
|
+
(stream === "stderr" ? this.err : this.out).write(text);
|
|
4884
|
+
this.partialOpen = stream === "stdout" ? !text.endsWith(`
|
|
4885
|
+
`) : this.partialOpen;
|
|
4886
|
+
}
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4889
|
+
function getDefaultChannel() {
|
|
4890
|
+
if (!defaultChannel)
|
|
4891
|
+
defaultChannel = new OutputChannel(defaultOutputBus);
|
|
4892
|
+
return defaultChannel;
|
|
4893
|
+
}
|
|
4894
|
+
var defaultChannel = null;
|
|
4895
|
+
var init_channel = __esm(() => {
|
|
4896
|
+
init_bus();
|
|
4897
|
+
init_format();
|
|
4898
|
+
});
|
|
4899
|
+
|
|
4900
|
+
// src/output/machine.ts
|
|
4901
|
+
function writeMachineJson(value) {
|
|
4902
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
4903
|
+
`);
|
|
4904
|
+
}
|
|
4905
|
+
function writeNonTtyLine(text) {
|
|
4906
|
+
process.stdout.write(text + `
|
|
4907
|
+
`);
|
|
4908
|
+
}
|
|
4909
|
+
|
|
4910
|
+
// src/output/index.ts
|
|
4911
|
+
var init_output = __esm(() => {
|
|
4912
|
+
init_bus();
|
|
4913
|
+
init_format();
|
|
4914
|
+
init_channel();
|
|
4915
|
+
});
|
|
4516
4916
|
|
|
4517
4917
|
// src/config/domains.ts
|
|
4518
4918
|
var exports_domains = {};
|
|
@@ -4569,7 +4969,7 @@ function loadDomainFiles(configDir) {
|
|
|
4569
4969
|
result = deepMerge(result, data);
|
|
4570
4970
|
anyLoaded = true;
|
|
4571
4971
|
} catch {
|
|
4572
|
-
|
|
4972
|
+
defaultOutputBus.log("warn", "config", t("config.parse_failed", { path: filePath }));
|
|
4573
4973
|
}
|
|
4574
4974
|
}
|
|
4575
4975
|
return anyLoaded ? result : null;
|
|
@@ -4602,6 +5002,7 @@ function domainForKey(key) {
|
|
|
4602
5002
|
var CONFIG_DOMAINS;
|
|
4603
5003
|
var init_domains = __esm(() => {
|
|
4604
5004
|
init_i18n();
|
|
5005
|
+
init_output();
|
|
4605
5006
|
CONFIG_DOMAINS = {
|
|
4606
5007
|
core: [
|
|
4607
5008
|
"version",
|
|
@@ -4690,7 +5091,7 @@ function loadJSON(path) {
|
|
|
4690
5091
|
try {
|
|
4691
5092
|
return JSON.parse(readFileSync4(path, "utf-8"), regexReviver);
|
|
4692
5093
|
} catch {
|
|
4693
|
-
|
|
5094
|
+
defaultOutputBus.log("warn", "config", t("config.parse_failed", { path }));
|
|
4694
5095
|
}
|
|
4695
5096
|
return null;
|
|
4696
5097
|
}
|
|
@@ -4803,11 +5204,11 @@ function loadConfig(options) {
|
|
|
4803
5204
|
backup.backupAll();
|
|
4804
5205
|
backup.backupConfig();
|
|
4805
5206
|
const summary = backup.getBackupSummary();
|
|
4806
|
-
|
|
5207
|
+
defaultOutputBus.log("info", "config", t("migration.detected", { summary }));
|
|
4807
5208
|
try {
|
|
4808
5209
|
unlinkSync(globalPath);
|
|
4809
5210
|
} catch (e) {
|
|
4810
|
-
|
|
5211
|
+
defaultOutputBus.log("error", "config", `[config] failed to remove legacy config.json: ${e instanceof Error ? e.message : String(e)}`);
|
|
4811
5212
|
}
|
|
4812
5213
|
}
|
|
4813
5214
|
let config = structuredClone(DEFAULTS);
|
|
@@ -4845,7 +5246,7 @@ function loadConfig(options) {
|
|
|
4845
5246
|
if (providerOverride)
|
|
4846
5247
|
providerOverride.envValue = config.provider;
|
|
4847
5248
|
} catch (e) {
|
|
4848
|
-
|
|
5249
|
+
defaultOutputBus.log("warn", "config", t("config.decryption_warning", { error: e.message }));
|
|
4849
5250
|
}
|
|
4850
5251
|
if (overrides.length > 0)
|
|
4851
5252
|
envOverrideMap.set(config, overrides);
|
|
@@ -4880,7 +5281,7 @@ function saveConfig(config, configPath, configDir) {
|
|
|
4880
5281
|
});
|
|
4881
5282
|
writeFileSync4(configPath, JSON.stringify(encryptedConfig, regexReplacer, 2), "utf-8");
|
|
4882
5283
|
} catch (e) {
|
|
4883
|
-
|
|
5284
|
+
defaultOutputBus.log("warn", "config", t("config.encryption_warning", { error: e.message }));
|
|
4884
5285
|
writeFileSync4(configPath, JSON.stringify(toWrite, regexReplacer, 2), "utf-8");
|
|
4885
5286
|
}
|
|
4886
5287
|
}
|
|
@@ -4894,6 +5295,7 @@ var init_config2 = __esm(() => {
|
|
|
4894
5295
|
init_backup();
|
|
4895
5296
|
init_encryption();
|
|
4896
5297
|
init_domains();
|
|
5298
|
+
init_output();
|
|
4897
5299
|
CONFIG_DIR = join6(homedir2(), ".mma");
|
|
4898
5300
|
CONFIG_FILE = join6(CONFIG_DIR, "config.json");
|
|
4899
5301
|
CONFIG_DOMAIN_DIR = join6(CONFIG_DIR, "config");
|
|
@@ -5091,82 +5493,9 @@ var init_file_log = __esm(() => {
|
|
|
5091
5493
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
5092
5494
|
});
|
|
5093
5495
|
|
|
5094
|
-
// node_modules/picocolors/picocolors.js
|
|
5095
|
-
var require_picocolors = __commonJS((exports, module) => {
|
|
5096
|
-
var p = process || {};
|
|
5097
|
-
var argv = p.argv || [];
|
|
5098
|
-
var env = p.env || {};
|
|
5099
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
5100
|
-
var formatter = (open, close, replace = open) => (input) => {
|
|
5101
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
5102
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
5103
|
-
};
|
|
5104
|
-
var replaceClose = (string, close, replace, index) => {
|
|
5105
|
-
let result = "", cursor = 0;
|
|
5106
|
-
do {
|
|
5107
|
-
result += string.substring(cursor, index) + replace;
|
|
5108
|
-
cursor = index + close.length;
|
|
5109
|
-
index = string.indexOf(close, cursor);
|
|
5110
|
-
} while (~index);
|
|
5111
|
-
return result + string.substring(cursor);
|
|
5112
|
-
};
|
|
5113
|
-
var createColors = (enabled = isColorSupported) => {
|
|
5114
|
-
let f = enabled ? formatter : () => String;
|
|
5115
|
-
return {
|
|
5116
|
-
isColorSupported: enabled,
|
|
5117
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
5118
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
5119
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
5120
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
5121
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
5122
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
5123
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
5124
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
5125
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
5126
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
5127
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
5128
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
5129
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
5130
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
5131
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
5132
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
5133
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
5134
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
5135
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
5136
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
5137
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
5138
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
5139
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
5140
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
5141
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
5142
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
5143
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
5144
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
5145
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
5146
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
5147
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
5148
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
5149
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
5150
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
5151
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
5152
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
5153
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
5154
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
5155
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
5156
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
5157
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
5158
|
-
};
|
|
5159
|
-
};
|
|
5160
|
-
module.exports = createColors();
|
|
5161
|
-
module.exports.createColors = createColors;
|
|
5162
|
-
});
|
|
5163
|
-
|
|
5164
5496
|
// src/logger/app-logger.ts
|
|
5165
5497
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync5, existsSync as existsSync8 } from "fs";
|
|
5166
5498
|
import { join as join8 } from "path";
|
|
5167
|
-
function isColorEnabled() {
|
|
5168
|
-
return !process.env.NO_COLOR && !process.env.CI && process.stdout.isTTY === true;
|
|
5169
|
-
}
|
|
5170
5499
|
|
|
5171
5500
|
class Logger {
|
|
5172
5501
|
level;
|
|
@@ -5174,9 +5503,11 @@ class Logger {
|
|
|
5174
5503
|
logDir = null;
|
|
5175
5504
|
sessionDir = null;
|
|
5176
5505
|
fileLog;
|
|
5177
|
-
|
|
5506
|
+
sink;
|
|
5507
|
+
constructor(level = "info", prefix = "", sink = defaultOutputBus) {
|
|
5178
5508
|
this.level = level;
|
|
5179
5509
|
this.prefix = prefix;
|
|
5510
|
+
this.sink = sink;
|
|
5180
5511
|
this.fileLog = new FileLogWriter;
|
|
5181
5512
|
}
|
|
5182
5513
|
setLevel(level) {
|
|
@@ -5226,7 +5557,7 @@ class Logger {
|
|
|
5226
5557
|
this.fileLog.logREPL(tag, sanitizeLogMessage(content));
|
|
5227
5558
|
}
|
|
5228
5559
|
child(prefix) {
|
|
5229
|
-
const childLogger = new Logger(this.level, this.prefix ? `${this.prefix}:${prefix}` : prefix);
|
|
5560
|
+
const childLogger = new Logger(this.level, this.prefix ? `${this.prefix}:${prefix}` : prefix, this.sink);
|
|
5230
5561
|
if (this.logDir)
|
|
5231
5562
|
childLogger.setLogDir(this.logDir);
|
|
5232
5563
|
if (this.sessionDir)
|
|
@@ -5251,10 +5582,11 @@ class Logger {
|
|
|
5251
5582
|
const sanitizedMsg = sanitizeLogMessage(msg);
|
|
5252
5583
|
const sanitizedMeta = meta ? this.sanitizeMeta(meta) : undefined;
|
|
5253
5584
|
const ts = new Date().toISOString();
|
|
5254
|
-
const prefix = this.prefix ? ` [${this.prefix}]` : "";
|
|
5255
5585
|
const metaStr = sanitizedMeta ? ` ${JSON.stringify(sanitizedMeta)}` : "";
|
|
5256
|
-
const line =
|
|
5257
|
-
|
|
5586
|
+
const line = `${sanitizedMsg}${metaStr}`;
|
|
5587
|
+
try {
|
|
5588
|
+
this.sink.emit({ level, source: this.prefix || "mma", kind: "log", text: line });
|
|
5589
|
+
} catch {}
|
|
5258
5590
|
this.fileLog.log(level.toUpperCase(), this.prefix || "MMA", `${ts} — ${sanitizedMsg}${metaStr}`);
|
|
5259
5591
|
const logTarget = this.sessionDir ?? this.logDir;
|
|
5260
5592
|
if (logTarget) {
|
|
@@ -5316,18 +5648,12 @@ class Logger {
|
|
|
5316
5648
|
} catch {}
|
|
5317
5649
|
}
|
|
5318
5650
|
}
|
|
5319
|
-
var
|
|
5651
|
+
var LEVELS;
|
|
5320
5652
|
var init_app_logger = __esm(() => {
|
|
5321
5653
|
init_data_sanitizer();
|
|
5322
5654
|
init_file_log();
|
|
5323
|
-
|
|
5655
|
+
init_output();
|
|
5324
5656
|
LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
5325
|
-
LEVEL_COLORS = {
|
|
5326
|
-
debug: (s) => import_picocolors.default.dim(s),
|
|
5327
|
-
info: (s) => s,
|
|
5328
|
-
warn: (s) => import_picocolors.default.yellow(s),
|
|
5329
|
-
error: (s) => import_picocolors.default.red(s)
|
|
5330
|
-
};
|
|
5331
5657
|
});
|
|
5332
5658
|
|
|
5333
5659
|
// node_modules/base64-js/index.js
|
|
@@ -7401,6 +7727,9 @@ class ToolExecutor {
|
|
|
7401
7727
|
setScope(scope) {
|
|
7402
7728
|
this.ctx.scope = scope;
|
|
7403
7729
|
}
|
|
7730
|
+
setPromptIO(io) {
|
|
7731
|
+
this.ctx.promptIO = io;
|
|
7732
|
+
}
|
|
7404
7733
|
getRecursionDepth() {
|
|
7405
7734
|
return this.ctx.recursionDepth ?? 0;
|
|
7406
7735
|
}
|
|
@@ -7765,7 +8094,7 @@ class AuditNotifier {
|
|
|
7765
8094
|
try {
|
|
7766
8095
|
await this.sendToWebhook(notification);
|
|
7767
8096
|
} catch (error) {
|
|
7768
|
-
|
|
8097
|
+
defaultOutputBus.log("warn", "audit", `[AuditNotifier] Webhook failed, adding to retry queue: ${error instanceof Error ? error.message : String(error)}`, { persist: true });
|
|
7769
8098
|
this.addToRetryQueue(notification);
|
|
7770
8099
|
}
|
|
7771
8100
|
}
|
|
@@ -7803,7 +8132,7 @@ class AuditNotifier {
|
|
|
7803
8132
|
appendFileSync3(this.config.filePath, line + `
|
|
7804
8133
|
`, "utf8");
|
|
7805
8134
|
} catch (error) {
|
|
7806
|
-
|
|
8135
|
+
defaultOutputBus.log("error", "audit", `[AuditNotifier] Failed to write to file: ${error instanceof Error ? error.message : String(error)}`, { persist: true });
|
|
7807
8136
|
}
|
|
7808
8137
|
}
|
|
7809
8138
|
async sendToWebhook(notification) {
|
|
@@ -7839,7 +8168,7 @@ class AuditNotifier {
|
|
|
7839
8168
|
while (this.retryQueue.length > 0) {
|
|
7840
8169
|
const item = this.retryQueue[0];
|
|
7841
8170
|
if (item.retries >= (this.config.maxRetries ?? 3)) {
|
|
7842
|
-
|
|
8171
|
+
defaultOutputBus.log("error", "audit", `[AuditNotifier] Max retries exceeded for notification: ${JSON.stringify(item.entry)}`, { persist: true });
|
|
7843
8172
|
this.retryQueue.shift();
|
|
7844
8173
|
continue;
|
|
7845
8174
|
}
|
|
@@ -7848,7 +8177,7 @@ class AuditNotifier {
|
|
|
7848
8177
|
this.retryQueue.shift();
|
|
7849
8178
|
} catch (error) {
|
|
7850
8179
|
item.retries++;
|
|
7851
|
-
|
|
8180
|
+
defaultOutputBus.log("warn", "audit", `[AuditNotifier] Webhook retry ${item.retries} failed: ${error instanceof Error ? error.message : String(error)}`, { persist: true });
|
|
7852
8181
|
const delay = backoffDelay(item.retries, 1000);
|
|
7853
8182
|
await new Promise((resolve3) => setTimeout(resolve3, delay));
|
|
7854
8183
|
}
|
|
@@ -7867,7 +8196,7 @@ class AuditNotifier {
|
|
|
7867
8196
|
`).filter(Boolean);
|
|
7868
8197
|
return lines.slice(-limit).map((line) => JSON.parse(line));
|
|
7869
8198
|
} catch (error) {
|
|
7870
|
-
|
|
8199
|
+
defaultOutputBus.log("error", "audit", `[AuditNotifier] Failed to read notifications: ${error instanceof Error ? error.message : String(error)}`, { persist: true });
|
|
7871
8200
|
return [];
|
|
7872
8201
|
}
|
|
7873
8202
|
}
|
|
@@ -7908,6 +8237,7 @@ function createAuditNotifier(config) {
|
|
|
7908
8237
|
}
|
|
7909
8238
|
var SEVERITY_WEIGHTS, DEFAULT_AUDIT_NOTIFIER_CONFIG, globalAuditNotifier;
|
|
7910
8239
|
var init_audit_notifier = __esm(() => {
|
|
8240
|
+
init_output();
|
|
7911
8241
|
SEVERITY_WEIGHTS = {
|
|
7912
8242
|
low: 1,
|
|
7913
8243
|
medium: 2,
|
|
@@ -8287,11 +8617,11 @@ var init_session_isolation = __esm(() => {
|
|
|
8287
8617
|
});
|
|
8288
8618
|
|
|
8289
8619
|
// src/ui/colors.ts
|
|
8290
|
-
var import_picocolors2, isTty = () => process.stdout.isTTY === true, enabled,
|
|
8620
|
+
var import_picocolors2, isTty = () => process.stdout.isTTY === true, enabled, pc;
|
|
8291
8621
|
var init_colors = __esm(() => {
|
|
8292
8622
|
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
8293
8623
|
enabled = isTty() && !process.env.CI && !process.env.NO_COLOR;
|
|
8294
|
-
|
|
8624
|
+
pc = import_picocolors2.createColors(enabled);
|
|
8295
8625
|
});
|
|
8296
8626
|
|
|
8297
8627
|
// src/ui/diff.ts
|
|
@@ -8401,11 +8731,11 @@ function formatLine(line, maxNumWidth) {
|
|
|
8401
8731
|
const num2 = line.type === "remove" ? line.oldNum : line.newNum;
|
|
8402
8732
|
const numStr = num2 !== null ? String(num2).padStart(maxNumWidth) : " ".repeat(maxNumWidth);
|
|
8403
8733
|
if (line.type === "remove") {
|
|
8404
|
-
return `${numStr} ${
|
|
8734
|
+
return `${numStr} ${pc.red("-")} ${line.content}`;
|
|
8405
8735
|
} else if (line.type === "add") {
|
|
8406
|
-
return `${numStr} ${
|
|
8736
|
+
return `${numStr} ${pc.green("+")} ${line.content}`;
|
|
8407
8737
|
} else if (line.content === "...") {
|
|
8408
|
-
return
|
|
8738
|
+
return pc.dim(` ${" ".repeat(maxNumWidth)}...`);
|
|
8409
8739
|
} else {
|
|
8410
8740
|
return ` ${numStr} ${line.content}`;
|
|
8411
8741
|
}
|
|
@@ -8418,7 +8748,7 @@ function generateDiff(oldContent, newContent) {
|
|
|
8418
8748
|
const newLines = newContent.split(`
|
|
8419
8749
|
`);
|
|
8420
8750
|
if (oldLines.length > MAX_LCS_INPUT_LINES || newLines.length > MAX_LCS_INPUT_LINES) {
|
|
8421
|
-
return
|
|
8751
|
+
return pc.dim(` ... (file too large for line diff: ${oldLines.length} -> ${newLines.length} lines)`);
|
|
8422
8752
|
}
|
|
8423
8753
|
const diff = buildDiff(oldLines, newLines);
|
|
8424
8754
|
if (diff.length === 0)
|
|
@@ -8431,7 +8761,7 @@ function generateDiff(oldContent, newContent) {
|
|
|
8431
8761
|
let lines = diff.map((l) => formatLine(l, maxNumWidth));
|
|
8432
8762
|
if (lines.length > MAX_DIFF_LINES) {
|
|
8433
8763
|
const truncated = lines.slice(0, MAX_DIFF_LINES);
|
|
8434
|
-
truncated.push(
|
|
8764
|
+
truncated.push(pc.dim(` ... (${lines.length - MAX_DIFF_LINES} more lines)`));
|
|
8435
8765
|
lines = truncated;
|
|
8436
8766
|
}
|
|
8437
8767
|
return lines.join(`
|
|
@@ -8444,11 +8774,11 @@ function generateNewFileDiff(content) {
|
|
|
8444
8774
|
const diffLines = [];
|
|
8445
8775
|
for (let i = 0;i < lines.length; i++) {
|
|
8446
8776
|
const numStr = String(i + 1).padStart(maxNumWidth);
|
|
8447
|
-
diffLines.push(`${numStr} ${
|
|
8777
|
+
diffLines.push(`${numStr} ${pc.green("+")} ${lines[i]}`);
|
|
8448
8778
|
}
|
|
8449
8779
|
if (diffLines.length > MAX_DIFF_LINES) {
|
|
8450
8780
|
const truncated = diffLines.slice(0, MAX_DIFF_LINES);
|
|
8451
|
-
truncated.push(
|
|
8781
|
+
truncated.push(pc.dim(` ... (${diffLines.length - MAX_DIFF_LINES} more lines)`));
|
|
8452
8782
|
return truncated.join(`
|
|
8453
8783
|
`);
|
|
8454
8784
|
}
|
|
@@ -8462,11 +8792,11 @@ function generateDeleteDiff(content) {
|
|
|
8462
8792
|
const diffLines = [];
|
|
8463
8793
|
for (let i = 0;i < lines.length; i++) {
|
|
8464
8794
|
const numStr = String(i + 1).padStart(maxNumWidth);
|
|
8465
|
-
diffLines.push(`${numStr} ${
|
|
8795
|
+
diffLines.push(`${numStr} ${pc.red("-")} ${lines[i]}`);
|
|
8466
8796
|
}
|
|
8467
8797
|
if (diffLines.length > MAX_DIFF_LINES) {
|
|
8468
8798
|
const truncated = diffLines.slice(0, MAX_DIFF_LINES);
|
|
8469
|
-
truncated.push(
|
|
8799
|
+
truncated.push(pc.dim(` ... (${diffLines.length - MAX_DIFF_LINES} more lines)`));
|
|
8470
8800
|
return truncated.join(`
|
|
8471
8801
|
`);
|
|
8472
8802
|
}
|
|
@@ -8474,7 +8804,7 @@ function generateDeleteDiff(content) {
|
|
|
8474
8804
|
`);
|
|
8475
8805
|
}
|
|
8476
8806
|
function generateMoveDiff(fromPath, toPath) {
|
|
8477
|
-
return [
|
|
8807
|
+
return [pc.red(` - ${fromPath}`), pc.green(` + ${toPath}`)].join(`
|
|
8478
8808
|
`);
|
|
8479
8809
|
}
|
|
8480
8810
|
var CONTEXT_LINES = 3, MAX_DIFF_LINES = 100, MAX_LCS_INPUT_LINES = 2000;
|
|
@@ -9877,6 +10207,7 @@ ${output}`;
|
|
|
9877
10207
|
output = `(exit code ${code})`;
|
|
9878
10208
|
}
|
|
9879
10209
|
output = npmExecHint(output);
|
|
10210
|
+
output = interactivePromptHint(output);
|
|
9880
10211
|
if (platform3() === "win32") {
|
|
9881
10212
|
const originalFirstWord = originalCommand.trim().split(/\s+/)[0]?.split(/[\\/]/).pop();
|
|
9882
10213
|
if (originalFirstWord && originalFirstWord in UNIX_TO_WIN_HINTS) {
|
|
@@ -9922,7 +10253,15 @@ Hint: ${t("exec.npm_exec_hint")}`;
|
|
|
9922
10253
|
}
|
|
9923
10254
|
return output;
|
|
9924
10255
|
}
|
|
9925
|
-
|
|
10256
|
+
function interactivePromptHint(output) {
|
|
10257
|
+
if (INTERACTIVE_PROMPT_RE.test(output)) {
|
|
10258
|
+
return `${output}
|
|
10259
|
+
|
|
10260
|
+
Hint: ${t("exec.interactive_hint")}`;
|
|
10261
|
+
}
|
|
10262
|
+
return output;
|
|
10263
|
+
}
|
|
10264
|
+
var BASH_GRACE_MS = 5000, SPAWN_SETTLE_MS = 100, BG_OUTPUT_PREVIEW_LINES = 15, bashGraceMs, FAILING_FIRST_WORDS, HARD_BLOCK_THRESHOLD = 3, UNIX_TO_WIN_HINTS, UNIX_TO_WIN_TRANSLATE, NEVER_TOOL_CALLS, CLI_FILE_RUN_RE, NPM_EXEC_RE, INTERACTIVE_PROMPT_RE, HIDDEN_PROCESS_TOOLS, bashTool;
|
|
9926
10265
|
var init_bash = __esm(() => {
|
|
9927
10266
|
init_command_validator();
|
|
9928
10267
|
init_audit_log();
|
|
@@ -10000,6 +10339,7 @@ var init_bash = __esm(() => {
|
|
|
10000
10339
|
]);
|
|
10001
10340
|
CLI_FILE_RUN_RE = /\b(bun|node|deno|python|python3|tsx|ts-node|php|ruby|go\s+run)\S*\s+(run\s+)?["']?[\w./\\-]+\.(ts|js|tsx|jsx|mjs|cjs|py)\b/;
|
|
10002
10341
|
NPM_EXEC_RE = /could not determine executable to run/i;
|
|
10342
|
+
INTERACTIVE_PROMPT_RE = /operation (?:cancelled|canceled|aborted)|stdin is not a tty|not a tty|cannot prompt without a tty/i;
|
|
10003
10343
|
HIDDEN_PROCESS_TOOLS = ["process_list", "process_log", "process_kill"];
|
|
10004
10344
|
bashTool = {
|
|
10005
10345
|
name: "bash",
|
|
@@ -14351,7 +14691,7 @@ function evaluateReasoningPolicy(input, state) {
|
|
|
14351
14691
|
var DECAY_THRESHOLD = 5;
|
|
14352
14692
|
|
|
14353
14693
|
// src/core/agent/constants.ts
|
|
14354
|
-
var TOOL_RESULT_MAX_TOKENS_RATIO = 0.3, TOOL_RESULT_ABSOLUTE_MAX_CHARS = 15000, QUALITY_TRIGGER_THRESHOLD = 40, TOOL_ARGS_SUMMARY_MAX_CHARS = 240, FORCED_COMPACTION_COOLDOWN = 3, MAX_LLM_ERROR_RETRIES = 2, MAX_HALLUCINATION_RETRIES = 3, MAX_CONSECUTIVE_TOOL_FAILURES = 5, MIN_REPEATED_TOOL_FAILURES = 3, MAX_AUDIT_RETRIES = 3, MAX_EMPTY_RESPONSE_RETRIES = 2, MAX_REPEATED_TOOL_CALLS = 2, MUTATION_CYCLE_NUDGE_THRESHOLD = 5;
|
|
14694
|
+
var TOOL_RESULT_MAX_TOKENS_RATIO = 0.3, TOOL_RESULT_ABSOLUTE_MAX_CHARS = 15000, QUALITY_TRIGGER_THRESHOLD = 40, TOOL_ARGS_SUMMARY_MAX_CHARS = 240, FORCED_COMPACTION_COOLDOWN = 3, MAX_LLM_ERROR_RETRIES = 2, MAX_HALLUCINATION_RETRIES = 3, MAX_CONSECUTIVE_TOOL_FAILURES = 5, MIN_REPEATED_TOOL_FAILURES = 3, MAX_AUDIT_RETRIES = 3, MAX_EMPTY_RESPONSE_RETRIES = 2, MAX_REPEATED_TOOL_CALLS = 2, MAX_REPEATED_TOOL_CALLS_INTERACTIVE = 5, MUTATION_CYCLE_NUDGE_THRESHOLD = 5;
|
|
14355
14695
|
|
|
14356
14696
|
// src/core/agent/loop-state.ts
|
|
14357
14697
|
function createLoopState() {
|
|
@@ -14617,7 +14957,10 @@ class ReasoningEffortResolver {
|
|
|
14617
14957
|
const overrideCooldown = reasoningConfig?.overrideCooldown ?? 0;
|
|
14618
14958
|
const overrideAge = state.iteration - reasoningState.overrideIteration;
|
|
14619
14959
|
const overrideActive = overrideCooldown > 0 && reasoningState.overrideIteration >= 0 && overrideAge > 0 && overrideAge <= overrideCooldown;
|
|
14620
|
-
if (
|
|
14960
|
+
if (reasoningState.manual) {
|
|
14961
|
+
level = reasoningState.level;
|
|
14962
|
+
source = "agent_override";
|
|
14963
|
+
} else if (overrideActive) {
|
|
14621
14964
|
level = reasoningState.level;
|
|
14622
14965
|
source = "agent_override";
|
|
14623
14966
|
} else if (reasoningConfig && reasoningConfig.mode === "auto" && deps.probePassed) {
|
|
@@ -14657,20 +15000,20 @@ class ContextRenderer {
|
|
|
14657
15000
|
const ctxPct = Math.min(100, Math.round(ctxTokens / ctxBudget.history * 100));
|
|
14658
15001
|
const barLen = 10;
|
|
14659
15002
|
const filled = Math.round(ctxPct / 100 * barLen);
|
|
14660
|
-
const ctxBar =
|
|
14661
|
-
const pctColor = ctxPct >= 75 ?
|
|
15003
|
+
const ctxBar = pc.green("█".repeat(filled)) + pc.dim("░".repeat(barLen - filled));
|
|
15004
|
+
const pctColor = ctxPct >= 75 ? pc.yellow : pc.dim;
|
|
14662
15005
|
const compCount = contextManager.getCompactionCount();
|
|
14663
15006
|
const quality = contextManager.getQuality();
|
|
14664
|
-
const qualityColor = quality >= 70 ?
|
|
15007
|
+
const qualityColor = quality >= 70 ? pc.green : quality >= 40 ? pc.yellow : pc.red;
|
|
14665
15008
|
onMeta?.(`
|
|
14666
|
-
${ctxBar} ${pctColor(`${ctxPct}%`)} ${
|
|
15009
|
+
${ctxBar} ${pctColor(`${ctxPct}%`)} ${pc.dim(`ctx: ${ctxTokens}/${ctxBudget.history}`)} ${pc.dim(`compactions: ${compCount}`)} ${qualityColor(`quality: ${quality}%`)}
|
|
14667
15010
|
`);
|
|
14668
15011
|
}
|
|
14669
15012
|
renderCompaction(contextManager, onMeta) {
|
|
14670
15013
|
const compCount = contextManager.getCompactionCount();
|
|
14671
15014
|
if (compCount > this.lastCompactionShown) {
|
|
14672
15015
|
this.lastCompactionShown = compCount;
|
|
14673
|
-
onMeta?.(
|
|
15016
|
+
onMeta?.(pc.dim(`
|
|
14674
15017
|
⟳ Context compacted (${compCount})
|
|
14675
15018
|
`));
|
|
14676
15019
|
}
|
|
@@ -14822,14 +15165,14 @@ class ToolBatchExecutor {
|
|
|
14822
15165
|
} else if (result.success) {
|
|
14823
15166
|
const metaOut = pluginManager.runOnMeta({ iteration, logger, contextManager }, result.output);
|
|
14824
15167
|
onMeta?.(`
|
|
14825
|
-
` +
|
|
15168
|
+
` + pc.dim(metaOut) + `
|
|
14826
15169
|
`);
|
|
14827
15170
|
} else {
|
|
14828
15171
|
const line = compactToolError(result.output);
|
|
14829
15172
|
const metaOut = line ? pluginManager.runOnMeta({ iteration, logger, contextManager }, line) : "";
|
|
14830
15173
|
if (metaOut)
|
|
14831
15174
|
onMeta?.(`
|
|
14832
|
-
` +
|
|
15175
|
+
` + pc.red(metaOut) + `
|
|
14833
15176
|
`);
|
|
14834
15177
|
}
|
|
14835
15178
|
if (result.diff) {
|
|
@@ -14983,7 +15326,7 @@ class HallucinationGate {
|
|
|
14983
15326
|
const warnLine = `${t("hall.uncertainty_prefix").trim()} ${reason ?? ""}`;
|
|
14984
15327
|
if (deps.onMeta) {
|
|
14985
15328
|
deps.onMeta(`
|
|
14986
|
-
${
|
|
15329
|
+
${pc.yellow(warnLine)}
|
|
14987
15330
|
`);
|
|
14988
15331
|
} else if (deps.onChunk) {
|
|
14989
15332
|
deps.onChunk(`
|
|
@@ -15341,7 +15684,12 @@ class Agent {
|
|
|
15341
15684
|
return this.reasoningState.level;
|
|
15342
15685
|
}
|
|
15343
15686
|
setReasoningLevel(level) {
|
|
15687
|
+
if (level === "auto") {
|
|
15688
|
+
this.reasoningState.manual = false;
|
|
15689
|
+
return;
|
|
15690
|
+
}
|
|
15344
15691
|
this.reasoningState.level = level;
|
|
15692
|
+
this.reasoningState.manual = true;
|
|
15345
15693
|
}
|
|
15346
15694
|
get currentIteration() {
|
|
15347
15695
|
return this._currentIteration;
|
|
@@ -15367,6 +15715,9 @@ class Agent {
|
|
|
15367
15715
|
this.deps.toolExecutor.setScope(this.deps.scope);
|
|
15368
15716
|
}
|
|
15369
15717
|
}
|
|
15718
|
+
setPromptIO(io) {
|
|
15719
|
+
this.deps.toolExecutor.setPromptIO(io);
|
|
15720
|
+
}
|
|
15370
15721
|
buildSystemPrompt() {
|
|
15371
15722
|
const systemBudget = Math.floor(this.deps.config.contextWindow * this.deps.config.contextBudget.systemPrompt);
|
|
15372
15723
|
const builder = new PromptBuilder(systemBudget);
|
|
@@ -15453,6 +15804,7 @@ class Agent {
|
|
|
15453
15804
|
this.deps.logger.warn(t("prompt.overflow.exceeded", {
|
|
15454
15805
|
label: w.label,
|
|
15455
15806
|
original: String(w.originalTokens),
|
|
15807
|
+
needed: String(needed),
|
|
15456
15808
|
budget: String(systemBudget),
|
|
15457
15809
|
mode: w.mode === "summary" ? "summarized" : "truncated",
|
|
15458
15810
|
resolved: String(w.resolvedTokens),
|
|
@@ -15714,7 +16066,7 @@ class Agent {
|
|
|
15714
16066
|
if (config.showReasoning) {
|
|
15715
16067
|
const metaOut = pluginManager.runOnMeta({ iteration: state.iteration, logger, contextManager }, chunk.content);
|
|
15716
16068
|
if (metaOut) {
|
|
15717
|
-
onMeta?.(
|
|
16069
|
+
onMeta?.(pc.dim(metaOut));
|
|
15718
16070
|
}
|
|
15719
16071
|
emittedReasoning = true;
|
|
15720
16072
|
}
|
|
@@ -15799,12 +16151,15 @@ class Agent {
|
|
|
15799
16151
|
role: "user",
|
|
15800
16152
|
content: `<system-summary>You just called the same tool with identical arguments. If the task is done, answer with a final text response NOW. If the command failed, try a different approach.</system-summary>`
|
|
15801
16153
|
});
|
|
16154
|
+
state.repeatedToolCount++;
|
|
15802
16155
|
if (this.deps.exitOnComplete) {
|
|
15803
|
-
state.repeatedToolCount++;
|
|
15804
16156
|
if (state.repeatedToolCount >= MAX_REPEATED_TOOL_CALLS) {
|
|
15805
16157
|
logger.debug("Exit-on-complete: repeated identical tool call, stopping");
|
|
15806
16158
|
break;
|
|
15807
16159
|
}
|
|
16160
|
+
} else if (state.repeatedToolCount >= MAX_REPEATED_TOOL_CALLS_INTERACTIVE && toolCalls.every((tc) => LOOP_PRONE_STATUS_TOOLS.has(tc.name))) {
|
|
16161
|
+
logger.warn(`Repeated identical status tool ${state.repeatedToolCount}× (iteration ${state.iteration}) — stopping to avoid an infinite loop`);
|
|
16162
|
+
break;
|
|
15808
16163
|
}
|
|
15809
16164
|
} else {
|
|
15810
16165
|
state.repeatedToolCount = 0;
|
|
@@ -16058,6 +16413,7 @@ class Agent {
|
|
|
16058
16413
|
});
|
|
16059
16414
|
}
|
|
16060
16415
|
}
|
|
16416
|
+
var LOOP_PRONE_STATUS_TOOLS;
|
|
16061
16417
|
var init_agent = __esm(() => {
|
|
16062
16418
|
init_manager();
|
|
16063
16419
|
init_factory();
|
|
@@ -16081,6 +16437,13 @@ var init_agent = __esm(() => {
|
|
|
16081
16437
|
init_audit_gate();
|
|
16082
16438
|
init_prompt_overflow();
|
|
16083
16439
|
init_tool_output();
|
|
16440
|
+
LOOP_PRONE_STATUS_TOOLS = new Set([
|
|
16441
|
+
"session_info",
|
|
16442
|
+
"process_list",
|
|
16443
|
+
"process_log",
|
|
16444
|
+
"file_info",
|
|
16445
|
+
"project_map"
|
|
16446
|
+
]);
|
|
16084
16447
|
});
|
|
16085
16448
|
|
|
16086
16449
|
// src/modules/context/fact-extractor.ts
|
|
@@ -16602,14 +16965,6 @@ class ConfidenceCheck {
|
|
|
16602
16965
|
};
|
|
16603
16966
|
}
|
|
16604
16967
|
const wordCount = response.split(/\s+/).filter(Boolean).length;
|
|
16605
|
-
const hasStructure = /```|^\s*[-*]\s|^\s*\d+\.\s|<[^>]+>/m.test(response);
|
|
16606
|
-
if (wordCount < MIN_WORDS && !hasStructure) {
|
|
16607
|
-
return {
|
|
16608
|
-
status: "warn",
|
|
16609
|
-
kind: "short",
|
|
16610
|
-
reason: t("hall.short_response")
|
|
16611
|
-
};
|
|
16612
|
-
}
|
|
16613
16968
|
if (this.previousResponse) {
|
|
16614
16969
|
const prevWords = this.previousResponse.split(/\s+/).filter(Boolean).length;
|
|
16615
16970
|
const bothSubstantive = response.length >= MIN_REPEAT_CHARS && this.previousResponse.length >= MIN_REPEAT_CHARS && wordCount >= MIN_REPEAT_WORDS && prevWords >= MIN_REPEAT_WORDS;
|
|
@@ -16653,7 +17008,7 @@ class ConfidenceCheck {
|
|
|
16653
17008
|
return matches / smaller;
|
|
16654
17009
|
}
|
|
16655
17010
|
}
|
|
16656
|
-
var MIN_CHARS = 1,
|
|
17011
|
+
var MIN_CHARS = 1, MIN_REPEAT_CHARS = 120, MIN_REPEAT_WORDS = 20, REPEAT_OVERLAP_THRESHOLD = 0.8;
|
|
16657
17012
|
var init_confidence = __esm(() => {
|
|
16658
17013
|
init_i18n();
|
|
16659
17014
|
});
|
|
@@ -18695,7 +19050,7 @@ class MCPClient {
|
|
|
18695
19050
|
this.pendingReject = null;
|
|
18696
19051
|
}
|
|
18697
19052
|
} catch (e) {
|
|
18698
|
-
|
|
19053
|
+
defaultOutputBus.log("error", "mcp", `[MCPClient] Unparseable SSE message: ${String(data).slice(0, 120)} ${e instanceof Error ? e.message : String(e)}`, { persist: true });
|
|
18699
19054
|
}
|
|
18700
19055
|
}
|
|
18701
19056
|
handleSSEError(err) {
|
|
@@ -19010,7 +19365,9 @@ class MCPClient {
|
|
|
19010
19365
|
}
|
|
19011
19366
|
}
|
|
19012
19367
|
var HTTP_TIMEOUT_MS = 1e4, MCP_ACCEPT_HEADER = "application/json, text/event-stream";
|
|
19013
|
-
var init_client = () => {
|
|
19368
|
+
var init_client = __esm(() => {
|
|
19369
|
+
init_output();
|
|
19370
|
+
});
|
|
19014
19371
|
|
|
19015
19372
|
// src/modules/mcp/registry.ts
|
|
19016
19373
|
class MCPRegistry {
|
|
@@ -23641,7 +23998,7 @@ class SessionFileEncryptor {
|
|
|
23641
23998
|
try {
|
|
23642
23999
|
return [this.decryptFileContent(line)];
|
|
23643
24000
|
} catch (e) {
|
|
23644
|
-
|
|
24001
|
+
defaultOutputBus.log("error", "security", `[session-encryption] failed to decrypt JSONL line — skipping it: ${e instanceof Error ? e.message : String(e)}`, { persist: true });
|
|
23645
24002
|
return [];
|
|
23646
24003
|
}
|
|
23647
24004
|
});
|
|
@@ -23720,6 +24077,7 @@ class SessionFileEncryptor {
|
|
|
23720
24077
|
var DEFAULT_SESSION_ENCRYPTION, globalSessionEncryptor;
|
|
23721
24078
|
var init_session_encryption = __esm(() => {
|
|
23722
24079
|
init_encryption();
|
|
24080
|
+
init_output();
|
|
23723
24081
|
DEFAULT_SESSION_ENCRYPTION = {
|
|
23724
24082
|
enabled: false,
|
|
23725
24083
|
encryptHistory: true,
|
|
@@ -23788,7 +24146,10 @@ class SessionStore {
|
|
|
23788
24146
|
mkdirSync17(dir, { recursive: true, mode: 448 });
|
|
23789
24147
|
const content = JSON.stringify(meta, null, 2);
|
|
23790
24148
|
if (this.encryptor) {
|
|
23791
|
-
writeFileSync16(this.metaPath(id), this.encryptor.encryptFileContent(content), {
|
|
24149
|
+
writeFileSync16(this.metaPath(id), this.encryptor.encryptFileContent(content), {
|
|
24150
|
+
encoding: "utf-8",
|
|
24151
|
+
mode: 384
|
|
24152
|
+
});
|
|
23792
24153
|
} else {
|
|
23793
24154
|
writeFileSync16(this.metaPath(id), content, { encoding: "utf-8", mode: 384 });
|
|
23794
24155
|
}
|
|
@@ -23828,7 +24189,10 @@ class SessionStore {
|
|
|
23828
24189
|
const line = JSON.stringify(msg);
|
|
23829
24190
|
if (this.encryptor?.isEnabled()) {
|
|
23830
24191
|
appendFileSync6(this.historyPath(id), this.encryptor.encryptFileContent(line) + `
|
|
23831
|
-
`, {
|
|
24192
|
+
`, {
|
|
24193
|
+
encoding: "utf-8",
|
|
24194
|
+
mode: 384
|
|
24195
|
+
});
|
|
23832
24196
|
} else {
|
|
23833
24197
|
appendFileSync6(this.historyPath(id), line + `
|
|
23834
24198
|
`, { encoding: "utf-8", mode: 384 });
|
|
@@ -23875,7 +24239,10 @@ class SessionStore {
|
|
|
23875
24239
|
const line = JSON.stringify(entry);
|
|
23876
24240
|
if (this.encryptor?.isEnabled()) {
|
|
23877
24241
|
appendFileSync6(this.sessionLogPath(id), this.encryptor.encryptFileContent(line) + `
|
|
23878
|
-
`, {
|
|
24242
|
+
`, {
|
|
24243
|
+
encoding: "utf-8",
|
|
24244
|
+
mode: 384
|
|
24245
|
+
});
|
|
23879
24246
|
} else {
|
|
23880
24247
|
appendFileSync6(this.sessionLogPath(id), line + `
|
|
23881
24248
|
`, { encoding: "utf-8", mode: 384 });
|
|
@@ -26833,7 +27200,7 @@ import { existsSync as existsSync51, readFileSync as readFileSync33, writeFileSy
|
|
|
26833
27200
|
import { join as join45, dirname as dirname18 } from "path";
|
|
26834
27201
|
import { homedir as homedir14 } from "os";
|
|
26835
27202
|
function cachePath() {
|
|
26836
|
-
return join45(homedir14(), ".mma", "reasoning-cache.json");
|
|
27203
|
+
return process.env.MMA_REASONING_CACHE ?? join45(homedir14(), ".mma", "reasoning-cache.json");
|
|
26837
27204
|
}
|
|
26838
27205
|
async function probeReasoningSupport(provider, strategy, signal) {
|
|
26839
27206
|
if (strategy === "none")
|
|
@@ -26989,7 +27356,8 @@ var exports_bootstrap = {};
|
|
|
26989
27356
|
__export(exports_bootstrap, {
|
|
26990
27357
|
setOneShotMode: () => setOneShotMode,
|
|
26991
27358
|
buildSystemInfo: () => buildSystemInfo,
|
|
26992
|
-
bootstrap: () => bootstrap
|
|
27359
|
+
bootstrap: () => bootstrap,
|
|
27360
|
+
applyReasoningCliOverride: () => applyReasoningCliOverride
|
|
26993
27361
|
});
|
|
26994
27362
|
import { homedir as homedir15 } from "os";
|
|
26995
27363
|
import { join as join46, resolve as resolve22 } from "path";
|
|
@@ -27154,11 +27522,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
27154
27522
|
if (!probe)
|
|
27155
27523
|
return null;
|
|
27156
27524
|
if (probe.actual < config.contextWindow) {
|
|
27157
|
-
logger4.warn
|
|
27525
|
+
logger4.logSilent("warn", `Context probe: model "${probe.model}" is loaded with ${probe.actual} tokens, but contextWindow is configured as ${config.contextWindow} — overflow/429 risk. Lower contextWindow or reload the model with a larger context.`);
|
|
27158
27526
|
} else if (probe.actual > config.contextWindow) {
|
|
27159
|
-
logger4.info
|
|
27527
|
+
logger4.logSilent("info", `Context probe: model "${probe.model}" supports ${probe.actual} tokens — consider "mma context ${probe.actual}" to use the full window.`);
|
|
27160
27528
|
} else {
|
|
27161
|
-
logger4.debug
|
|
27529
|
+
logger4.logSilent("debug", `Context probe: configured contextWindow matches loaded context (${probe.actual})`);
|
|
27162
27530
|
}
|
|
27163
27531
|
return probe;
|
|
27164
27532
|
} catch {
|
|
@@ -27183,7 +27551,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
27183
27551
|
const passed = cached !== undefined ? cached : await probeReasoningSupport2(llmProvider, reasoningStrategy);
|
|
27184
27552
|
if (cached === undefined && passed !== null)
|
|
27185
27553
|
setCachedProbeResult2(cacheK, passed);
|
|
27186
|
-
logger4.info
|
|
27554
|
+
logger4.logSilent("info", t("env.reasoning_probe", {
|
|
27187
27555
|
strategy: reasoningStrategy,
|
|
27188
27556
|
result: passed === true ? t("env.reasoning_respected") : t("env.reasoning_ignored")
|
|
27189
27557
|
}));
|
|
@@ -27411,11 +27779,13 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
|
|
|
27411
27779
|
const dry = dryRunOverflow([...promptBlocks, ...dynamicBlocks], systemBudget);
|
|
27412
27780
|
if (dry.overflow.length > 0) {
|
|
27413
27781
|
const overflowTokens = dry.overflow.reduce((s, b) => s + b.estimatedTokens, 0);
|
|
27414
|
-
const
|
|
27782
|
+
const needed = dry.includedTokens + overflowTokens;
|
|
27783
|
+
const hint = overflowHint(config, dir, needed);
|
|
27415
27784
|
for (const b of dry.overflow) {
|
|
27416
27785
|
logger4.warn(t("prompt.overflow.startup", {
|
|
27417
27786
|
block: b.kind === "instructions" ? "AGENTS.md" : "project map",
|
|
27418
27787
|
original: String(b.estimatedTokens),
|
|
27788
|
+
needed: String(needed),
|
|
27419
27789
|
budget: String(systemBudget),
|
|
27420
27790
|
hint
|
|
27421
27791
|
}));
|
|
@@ -27871,12 +28241,12 @@ function formatTable(tableLines, opts = {}) {
|
|
|
27871
28241
|
const a = isHeader && align[c] === undefined ? "center" : align[c] ?? "left";
|
|
27872
28242
|
cells.push(pad(cell, widths[c], a));
|
|
27873
28243
|
}
|
|
27874
|
-
const content = cells.map((c) =>
|
|
27875
|
-
return isHeader ?
|
|
28244
|
+
const content = cells.map((c) => pc.dim("│ ") + c).join("") + pc.dim("│");
|
|
28245
|
+
return isHeader ? pc.bold(content) : content;
|
|
27876
28246
|
};
|
|
27877
28247
|
const border = (l, m, r) => {
|
|
27878
28248
|
const seg = widths.map((w) => "─".repeat(w + 2)).join(m);
|
|
27879
|
-
return
|
|
28249
|
+
return pc.dim(l + seg + r);
|
|
27880
28250
|
};
|
|
27881
28251
|
const out = [];
|
|
27882
28252
|
out.push(border("┌", "┬", "┐"));
|
|
@@ -27925,12 +28295,14 @@ class Spinner {
|
|
|
27925
28295
|
frame = 0;
|
|
27926
28296
|
message = "";
|
|
27927
28297
|
enabled;
|
|
28298
|
+
channel;
|
|
27928
28299
|
stream;
|
|
27929
28300
|
intervalMs;
|
|
27930
28301
|
width;
|
|
27931
28302
|
constructor(opts = {}) {
|
|
27932
|
-
this.
|
|
27933
|
-
this.
|
|
28303
|
+
this.channel = opts.channel;
|
|
28304
|
+
this.stream = process.stderr;
|
|
28305
|
+
this.enabled = opts.enabled ?? isSpinnerSupported();
|
|
27934
28306
|
this.intervalMs = opts.intervalMs ?? 80;
|
|
27935
28307
|
this.width = opts.width ?? getTerminalWidth();
|
|
27936
28308
|
}
|
|
@@ -27955,7 +28327,11 @@ class Spinner {
|
|
|
27955
28327
|
if (this.timer) {
|
|
27956
28328
|
clearInterval(this.timer);
|
|
27957
28329
|
this.timer = null;
|
|
27958
|
-
|
|
28330
|
+
const clear = "\r\x1B[K";
|
|
28331
|
+
if (this.channel)
|
|
28332
|
+
this.channel.writeOverlay(clear);
|
|
28333
|
+
else
|
|
28334
|
+
this.stream.write(clear);
|
|
27959
28335
|
}
|
|
27960
28336
|
}
|
|
27961
28337
|
truncate(text) {
|
|
@@ -27974,7 +28350,11 @@ class Spinner {
|
|
|
27974
28350
|
return;
|
|
27975
28351
|
const frame2 = FRAMES[this.frame % FRAMES.length];
|
|
27976
28352
|
this.frame++;
|
|
27977
|
-
|
|
28353
|
+
const text = "\r" + pc.cyan(frame2) + " " + this.message + "\x1B[K";
|
|
28354
|
+
if (this.channel)
|
|
28355
|
+
this.channel.writeOverlay(text);
|
|
28356
|
+
else
|
|
28357
|
+
this.stream.write(text);
|
|
27978
28358
|
}
|
|
27979
28359
|
}
|
|
27980
28360
|
var FRAMES;
|
|
@@ -28041,19 +28421,19 @@ function box(lines, opts = {}) {
|
|
|
28041
28421
|
const title = opts.title ?? "";
|
|
28042
28422
|
if (title) {
|
|
28043
28423
|
const head = `─ ${title} `;
|
|
28044
|
-
out.push(
|
|
28424
|
+
out.push(pc.dim(`┌${head}${"─".repeat(Math.max(0, width - 2 - stringWidth(head)))}┐`));
|
|
28045
28425
|
} else {
|
|
28046
|
-
out.push(
|
|
28426
|
+
out.push(pc.dim(`┌${"─".repeat(width - 2)}┐`));
|
|
28047
28427
|
}
|
|
28048
28428
|
for (const line of wrapped) {
|
|
28049
|
-
out.push(
|
|
28429
|
+
out.push(pc.dim("│") + " ".repeat(pad2) + padTo(line, inner) + " ".repeat(pad2) + pc.dim("│"));
|
|
28050
28430
|
}
|
|
28051
|
-
out.push(
|
|
28431
|
+
out.push(pc.dim(`└${"─".repeat(width - 2)}┘`));
|
|
28052
28432
|
return out;
|
|
28053
28433
|
}
|
|
28054
28434
|
function divider(width) {
|
|
28055
28435
|
const w = Math.min(width ?? getTerminalWidth(), 60);
|
|
28056
|
-
return
|
|
28436
|
+
return pc.dim("─".repeat(w));
|
|
28057
28437
|
}
|
|
28058
28438
|
var init_box = __esm(() => {
|
|
28059
28439
|
init_string_width();
|
|
@@ -28061,10 +28441,59 @@ var init_box = __esm(() => {
|
|
|
28061
28441
|
init_table();
|
|
28062
28442
|
});
|
|
28063
28443
|
|
|
28444
|
+
// src/cli/setup-prompt.ts
|
|
28445
|
+
class SetupPrompt {
|
|
28446
|
+
input;
|
|
28447
|
+
output;
|
|
28448
|
+
pending = null;
|
|
28449
|
+
buffer = "";
|
|
28450
|
+
closed = false;
|
|
28451
|
+
onData;
|
|
28452
|
+
constructor(input = process.stdin, output = process.stdout) {
|
|
28453
|
+
this.input = input;
|
|
28454
|
+
this.output = output;
|
|
28455
|
+
if (typeof this.input.setRawMode === "function")
|
|
28456
|
+
this.input.setRawMode(false);
|
|
28457
|
+
this.onData = (buf) => this.consume(buf.toString("utf-8"));
|
|
28458
|
+
this.input.on("data", this.onData);
|
|
28459
|
+
this.input.resume?.();
|
|
28460
|
+
}
|
|
28461
|
+
question(query, cb) {
|
|
28462
|
+
if (this.closed)
|
|
28463
|
+
return;
|
|
28464
|
+
this.buffer = "";
|
|
28465
|
+
this.pending = cb;
|
|
28466
|
+
this.output.write(query);
|
|
28467
|
+
}
|
|
28468
|
+
close() {
|
|
28469
|
+
if (this.closed)
|
|
28470
|
+
return;
|
|
28471
|
+
this.closed = true;
|
|
28472
|
+
this.pending = null;
|
|
28473
|
+
this.input.removeListener("data", this.onData);
|
|
28474
|
+
this.input.pause?.();
|
|
28475
|
+
}
|
|
28476
|
+
consume(text) {
|
|
28477
|
+
if (!this.pending || this.closed)
|
|
28478
|
+
return;
|
|
28479
|
+
this.buffer += text;
|
|
28480
|
+
const idx = this.buffer.search(/[\r\n]/);
|
|
28481
|
+
if (idx === -1)
|
|
28482
|
+
return;
|
|
28483
|
+
const answer = this.buffer.slice(0, idx);
|
|
28484
|
+
this.buffer = "";
|
|
28485
|
+
const cb = this.pending;
|
|
28486
|
+
this.pending = null;
|
|
28487
|
+
if (!this.output.isTTY)
|
|
28488
|
+
this.output.write(`
|
|
28489
|
+
`);
|
|
28490
|
+
cb(answer);
|
|
28491
|
+
}
|
|
28492
|
+
}
|
|
28493
|
+
|
|
28064
28494
|
// src/cli/setup.ts
|
|
28065
|
-
import * as readline from "readline";
|
|
28066
28495
|
async function withSpinner(message, fn) {
|
|
28067
|
-
const spinner = new Spinner;
|
|
28496
|
+
const spinner = new Spinner({ channel: getDefaultChannel() });
|
|
28068
28497
|
spinner.start(message);
|
|
28069
28498
|
try {
|
|
28070
28499
|
return await fn();
|
|
@@ -28073,9 +28502,9 @@ async function withSpinner(message, fn) {
|
|
|
28073
28502
|
}
|
|
28074
28503
|
}
|
|
28075
28504
|
function menuList(items) {
|
|
28076
|
-
const lines = items.map((it, i) => ` ${
|
|
28505
|
+
const lines = items.map((it, i) => ` ${pc.cyan(`[${i + 1}]`)} ${it.label}${it.url ? ` ${pc.dim(it.url)}` : ""}`);
|
|
28077
28506
|
for (const l of box(lines, { width: 72 }))
|
|
28078
|
-
|
|
28507
|
+
getDefaultChannel().writeLine(l);
|
|
28079
28508
|
}
|
|
28080
28509
|
function ask(rl, question, defaultValue) {
|
|
28081
28510
|
return new Promise((resolve23) => {
|
|
@@ -28085,6 +28514,12 @@ function ask(rl, question, defaultValue) {
|
|
|
28085
28514
|
});
|
|
28086
28515
|
});
|
|
28087
28516
|
}
|
|
28517
|
+
function askInt(rl, question, defaultValue) {
|
|
28518
|
+
return ask(rl, question, String(defaultValue)).then((raw) => {
|
|
28519
|
+
const n = parseInt(raw, 10);
|
|
28520
|
+
return Number.isFinite(n) && n > 0 ? n : defaultValue;
|
|
28521
|
+
});
|
|
28522
|
+
}
|
|
28088
28523
|
async function scanPorts() {
|
|
28089
28524
|
const found = [];
|
|
28090
28525
|
for (const { port, label } of KNOWN_PORTS) {
|
|
@@ -28154,16 +28589,17 @@ async function testChat(apiBase, apiKey, model) {
|
|
|
28154
28589
|
}
|
|
28155
28590
|
}
|
|
28156
28591
|
async function runSetup(externalRl) {
|
|
28157
|
-
|
|
28158
|
-
const rl = externalRl
|
|
28159
|
-
input: process.stdin,
|
|
28160
|
-
output: process.stdout
|
|
28161
|
-
});
|
|
28592
|
+
getDefaultChannel().writeLine(t("setup.title"));
|
|
28593
|
+
const rl = externalRl ?? new SetupPrompt;
|
|
28162
28594
|
const ownRl = !externalRl;
|
|
28163
|
-
|
|
28164
|
-
|
|
28595
|
+
getDefaultChannel().writeLine(t("setup.language"));
|
|
28596
|
+
menuList(LANGUAGES);
|
|
28597
|
+
const languageChoice = await ask(rl, t("setup.select_language_num", { max: LANGUAGES.length }), "1");
|
|
28598
|
+
const typedLang = languageChoice.trim().toLowerCase();
|
|
28599
|
+
const byCode = LANGUAGES.find((l) => l.value === typedLang);
|
|
28600
|
+
const locale = byCode ? byCode.value : LANGUAGES[Math.max(0, Math.min(LANGUAGES.length - 1, (parseInt(languageChoice) || 1) - 1))].value;
|
|
28165
28601
|
setLocale(locale);
|
|
28166
|
-
|
|
28602
|
+
getDefaultChannel().writeLine(t("setup.select_provider"));
|
|
28167
28603
|
menuList(PROVIDER_TYPES);
|
|
28168
28604
|
const providerChoice = await ask(rl, t("setup.select_provider_num", { max: PROVIDER_TYPES.length }), "1");
|
|
28169
28605
|
const providerIdx = Math.max(0, Math.min(PROVIDER_TYPES.length - 1, (parseInt(providerChoice) || 1) - 1));
|
|
@@ -28172,7 +28608,7 @@ async function runSetup(externalRl) {
|
|
|
28172
28608
|
if (provider === "openai-compat") {
|
|
28173
28609
|
const found = await withSpinner(t("setup.scanning_spinner"), async () => scanPorts());
|
|
28174
28610
|
if (found.length > 0) {
|
|
28175
|
-
|
|
28611
|
+
getDefaultChannel().writeLine(t("setup.found_servers", { count: found.length }));
|
|
28176
28612
|
menuList([
|
|
28177
28613
|
...found.map((f) => ({ label: f.label, url: f.url })),
|
|
28178
28614
|
{ label: t("setup.custom_url") }
|
|
@@ -28185,7 +28621,7 @@ async function runSetup(externalRl) {
|
|
|
28185
28621
|
apiBase = found[Math.max(0, Math.min(found.length - 1, idx))].url;
|
|
28186
28622
|
}
|
|
28187
28623
|
} else {
|
|
28188
|
-
|
|
28624
|
+
getDefaultChannel().writeLine(t("setup.no_servers"));
|
|
28189
28625
|
apiBase = await ask(rl, t("setup.api_base"), "http://localhost:1234/v1");
|
|
28190
28626
|
}
|
|
28191
28627
|
} else {
|
|
@@ -28196,7 +28632,7 @@ async function runSetup(externalRl) {
|
|
|
28196
28632
|
const models = await withSpinner(t("setup.fetching_spinner"), () => fetchModels(apiBase, apiKey));
|
|
28197
28633
|
let model = "";
|
|
28198
28634
|
if (models.length > 0) {
|
|
28199
|
-
|
|
28635
|
+
getDefaultChannel().writeLine(t("setup.available_models"));
|
|
28200
28636
|
menuList(models.slice(0, 10).map((m) => ({ label: m })));
|
|
28201
28637
|
const choice = await ask(rl, t("setup.select_model", { max: Math.min(models.length, 10) }), "1");
|
|
28202
28638
|
const idx = Math.max(0, Math.min(models.length - 1, (parseInt(choice) || 1) - 1));
|
|
@@ -28206,15 +28642,15 @@ async function runSetup(externalRl) {
|
|
|
28206
28642
|
}
|
|
28207
28643
|
const connected = await withSpinner(t("setup.testing_spinner", { model }), () => testChat(apiBase, apiKey, model));
|
|
28208
28644
|
if (connected) {
|
|
28209
|
-
|
|
28645
|
+
getDefaultChannel().writeLine(pc.green(t("setup.ok")));
|
|
28210
28646
|
} else {
|
|
28211
|
-
|
|
28647
|
+
getDefaultChannel().writeLine(pc.yellow(t("setup.warning")));
|
|
28212
28648
|
}
|
|
28213
|
-
|
|
28214
|
-
const contextWindow =
|
|
28215
|
-
const maxIterations =
|
|
28216
|
-
|
|
28217
|
-
|
|
28649
|
+
getDefaultChannel().writeLine(t("setup.agent_settings"));
|
|
28650
|
+
const contextWindow = await askInt(rl, t("setup.context_window"), 32768);
|
|
28651
|
+
const maxIterations = await askInt(rl, t("setup.max_iters"), 1000);
|
|
28652
|
+
getDefaultChannel().writeLine(t("setup.security_header"));
|
|
28653
|
+
getDefaultChannel().writeLine(pc.dim(t("setup.security_status_on")));
|
|
28218
28654
|
const configureSecurity = await ask(rl, t("setup.security_configure"), "n");
|
|
28219
28655
|
let securityBashBlock = false;
|
|
28220
28656
|
let securityFlagsBlock = false;
|
|
@@ -28226,13 +28662,6 @@ async function runSetup(externalRl) {
|
|
|
28226
28662
|
}
|
|
28227
28663
|
if (ownRl) {
|
|
28228
28664
|
rl.close();
|
|
28229
|
-
process.stdin.removeAllListeners("data");
|
|
28230
|
-
process.stdin.removeAllListeners("keypress");
|
|
28231
|
-
if (typeof process.stdin.setRawMode === "function") {
|
|
28232
|
-
process.stdin.setRawMode(false);
|
|
28233
|
-
}
|
|
28234
|
-
process.stdin.pause();
|
|
28235
|
-
process.stdin.resume();
|
|
28236
28665
|
}
|
|
28237
28666
|
const answers = {
|
|
28238
28667
|
provider,
|
|
@@ -28246,34 +28675,37 @@ async function runSetup(externalRl) {
|
|
|
28246
28675
|
securityFlagsBlock,
|
|
28247
28676
|
securityPathsDeny
|
|
28248
28677
|
};
|
|
28249
|
-
|
|
28250
|
-
const summary =
|
|
28251
|
-
t("setup.
|
|
28252
|
-
t("setup.
|
|
28253
|
-
t("setup.
|
|
28254
|
-
t("setup.
|
|
28255
|
-
|
|
28256
|
-
[t("setup.
|
|
28257
|
-
[
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
28261
|
-
|
|
28262
|
-
console.log(l);
|
|
28678
|
+
getDefaultChannel().writeLine(pc.green(pc.bold(t("setup.complete"))));
|
|
28679
|
+
const summary = [
|
|
28680
|
+
[t("setup.provider_type"), provider],
|
|
28681
|
+
[t("setup.model_name"), model],
|
|
28682
|
+
[t("setup.api_base"), apiBase],
|
|
28683
|
+
[t("setup.api_key"), apiKey || "not-needed"],
|
|
28684
|
+
[t("setup.context_window"), String(contextWindow)],
|
|
28685
|
+
[t("setup.max_iters"), String(maxIterations)],
|
|
28686
|
+
[t("setup.ui_lang"), locale]
|
|
28687
|
+
];
|
|
28688
|
+
for (const [label, value] of summary) {
|
|
28689
|
+
getDefaultChannel().writeLine(` ${pc.yellow(label.trim())}: ${pc.white(value)}`);
|
|
28690
|
+
}
|
|
28263
28691
|
return answers;
|
|
28264
28692
|
}
|
|
28265
|
-
var PROVIDER_TYPES, KNOWN_PORTS;
|
|
28693
|
+
var PROVIDER_TYPES, LANGUAGES, KNOWN_PORTS;
|
|
28266
28694
|
var init_setup = __esm(() => {
|
|
28267
28695
|
init_colors();
|
|
28268
28696
|
init_i18n();
|
|
28269
28697
|
init_spinner();
|
|
28270
28698
|
init_presets();
|
|
28271
28699
|
init_box();
|
|
28272
|
-
|
|
28700
|
+
init_output();
|
|
28273
28701
|
PROVIDER_TYPES = BUILTIN_PROVIDERS.map((spec) => ({
|
|
28274
28702
|
value: spec.type,
|
|
28275
28703
|
label: spec.label
|
|
28276
28704
|
}));
|
|
28705
|
+
LANGUAGES = [
|
|
28706
|
+
{ value: "en", label: "English" },
|
|
28707
|
+
{ value: "ru", label: "Русский" }
|
|
28708
|
+
];
|
|
28277
28709
|
KNOWN_PORTS = [
|
|
28278
28710
|
{ port: 1234, label: "LM Studio" },
|
|
28279
28711
|
{ port: 11434, label: "Ollama" },
|
|
@@ -36368,35 +36800,35 @@ async function certify(opts) {
|
|
|
36368
36800
|
const providerUrl = opts.providerUrl || opts.config.provider.baseUrl;
|
|
36369
36801
|
const { scenarios, errors: errors2 } = loadScenarios(join52(opts.projectDir, ".mma", "certification", "scenarios"));
|
|
36370
36802
|
for (const e of errors2)
|
|
36371
|
-
|
|
36803
|
+
getDefaultChannel().writeLine(pc.yellow(` ${e}`), "stderr");
|
|
36372
36804
|
let selected = filterByTags(scenarios, opts.tags);
|
|
36373
36805
|
const isPartial = Array.isArray(opts.scenarios) && opts.scenarios.length > 0;
|
|
36374
36806
|
if (isPartial) {
|
|
36375
36807
|
const unknown = unknownScenarioIds(scenarios, opts.scenarios);
|
|
36376
36808
|
if (unknown.length > 0) {
|
|
36377
|
-
|
|
36809
|
+
getDefaultChannel().writeLine(pc.red(t("cli.cert_scenarios_unknown", {
|
|
36378
36810
|
ids: unknown.join(", "),
|
|
36379
36811
|
available: scenarios.map((s) => s.id).join(", ")
|
|
36380
|
-
})));
|
|
36812
|
+
})), "stderr");
|
|
36381
36813
|
process.exitCode = 1;
|
|
36382
36814
|
return;
|
|
36383
36815
|
}
|
|
36384
36816
|
selected = filterByScenarios(scenarios, opts.scenarios);
|
|
36385
36817
|
}
|
|
36386
36818
|
if (selected.length === 0) {
|
|
36387
|
-
|
|
36819
|
+
getDefaultChannel().writeLine(pc.red(t("cli.cert_no_scenarios", { tags: opts.tags.join(",") })), "stderr");
|
|
36388
36820
|
process.exitCode = 1;
|
|
36389
36821
|
return;
|
|
36390
36822
|
}
|
|
36391
36823
|
const manifest = readMergedManifest(opts.projectDir);
|
|
36392
36824
|
const existing = manifest.certifications.find((e) => e.model === opts.name && e.providerUrl === providerUrl);
|
|
36393
36825
|
if (existing && !opts.force && !isPartial) {
|
|
36394
|
-
|
|
36395
|
-
|
|
36826
|
+
getDefaultChannel().writeLine(pc.yellow(t("cli.cert_exists", { model: opts.name })), "stderr");
|
|
36827
|
+
getDefaultChannel().writeLine(pc.yellow(t("cli.cert_exists_hint")), "stderr");
|
|
36396
36828
|
process.exitCode = 1;
|
|
36397
36829
|
return;
|
|
36398
36830
|
}
|
|
36399
|
-
|
|
36831
|
+
getDefaultChannel().writeLine(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
|
|
36400
36832
|
const sandboxBase = join52(process.cwd(), ".mma", "certification");
|
|
36401
36833
|
const results = [];
|
|
36402
36834
|
const total = selected.length;
|
|
@@ -36404,7 +36836,7 @@ async function certify(opts) {
|
|
|
36404
36836
|
for (const scenario of selected) {
|
|
36405
36837
|
idx++;
|
|
36406
36838
|
if (scenario.mode === "skip") {
|
|
36407
|
-
|
|
36839
|
+
getDefaultChannel().writeLine(pc.dim(`[${idx}/${total}] ${scenario.id} ... skipped`));
|
|
36408
36840
|
results.push({
|
|
36409
36841
|
id: scenario.id,
|
|
36410
36842
|
title: scenario.title,
|
|
@@ -36426,10 +36858,10 @@ async function certify(opts) {
|
|
|
36426
36858
|
timeoutMs: opts.timeout,
|
|
36427
36859
|
baseConfig: opts.config,
|
|
36428
36860
|
onRep: (id, rep, reps, passed, failures) => {
|
|
36429
|
-
const word = passed ?
|
|
36430
|
-
|
|
36861
|
+
const word = passed ? pc.green(t("cli.cert_rep_pass")) : pc.red(t("cli.cert_rep_fail"));
|
|
36862
|
+
getDefaultChannel().writeLine(`[${idx}/${total}] ${id} (${rep}/${reps})... ${word}`);
|
|
36431
36863
|
if (!passed)
|
|
36432
|
-
|
|
36864
|
+
getDefaultChannel().writeLine(` ${pc.dim(failures.join("; "))}`);
|
|
36433
36865
|
}
|
|
36434
36866
|
});
|
|
36435
36867
|
results.push(res);
|
|
@@ -36452,7 +36884,7 @@ async function certify(opts) {
|
|
|
36452
36884
|
results: finalResults
|
|
36453
36885
|
};
|
|
36454
36886
|
upsertCertification(entry);
|
|
36455
|
-
|
|
36887
|
+
getDefaultChannel().writeLine(t("cli.cert_done", {
|
|
36456
36888
|
passed: String(suite.passed),
|
|
36457
36889
|
failed: String(suite.failed),
|
|
36458
36890
|
skipped: String(suite.skipped),
|
|
@@ -36460,10 +36892,10 @@ async function certify(opts) {
|
|
|
36460
36892
|
}));
|
|
36461
36893
|
printResults(finalResults);
|
|
36462
36894
|
if (isFullyPassed(entry)) {
|
|
36463
|
-
|
|
36895
|
+
getDefaultChannel().writeLine(pc.green(`
|
|
36464
36896
|
✔ ${opts.name} is certified`));
|
|
36465
36897
|
} else {
|
|
36466
|
-
|
|
36898
|
+
getDefaultChannel().writeLine(pc.yellow(`
|
|
36467
36899
|
⚠ ${opts.name} is NOT certified — all scenarios must pass`));
|
|
36468
36900
|
}
|
|
36469
36901
|
writeReport(entry, opts.projectDir);
|
|
@@ -36473,25 +36905,25 @@ async function certStatus(name, config, projectDir) {
|
|
|
36473
36905
|
const providerUrl = config.provider.baseUrl;
|
|
36474
36906
|
const entry = m.certifications.find((e) => e.model === name && e.providerUrl === providerUrl);
|
|
36475
36907
|
if (!entry) {
|
|
36476
|
-
|
|
36908
|
+
getDefaultChannel().writeLine(t("cli.cert_not_found", { model: name }));
|
|
36477
36909
|
return;
|
|
36478
36910
|
}
|
|
36479
|
-
|
|
36480
|
-
|
|
36481
|
-
|
|
36482
|
-
const status = isFullyPassed(entry) ?
|
|
36483
|
-
|
|
36911
|
+
getDefaultChannel().writeLine(`${t("cli.cert_provider_col")}: ${entry.providerUrl}`);
|
|
36912
|
+
getDefaultChannel().writeLine(`${t("cli.cert_version_col")}: ${entry.mmaVersion} ${t("cli.cert_date_col")}: ${entry.certifiedAt.slice(0, 10)}`);
|
|
36913
|
+
getDefaultChannel().writeLine(`${t("cli.cert_suite_col")}: ${entry.suite.passed} pass / ${entry.suite.failed} fail / ${entry.suite.skipped} skipped`);
|
|
36914
|
+
const status = isFullyPassed(entry) ? pc.green("✔ certified") : pc.yellow("⚠ NOT certified");
|
|
36915
|
+
getDefaultChannel().writeLine(`Status: ${status}`);
|
|
36484
36916
|
printResults(entry.results);
|
|
36485
36917
|
}
|
|
36486
36918
|
async function certList(projectDir) {
|
|
36487
36919
|
const m = readMergedManifest(projectDir);
|
|
36488
36920
|
if (m.certifications.length === 0) {
|
|
36489
|
-
|
|
36921
|
+
getDefaultChannel().writeLine(t("cli.cert_empty"));
|
|
36490
36922
|
return;
|
|
36491
36923
|
}
|
|
36492
36924
|
for (const e of m.certifications) {
|
|
36493
|
-
const mark = isFullyPassed(e) ?
|
|
36494
|
-
|
|
36925
|
+
const mark = isFullyPassed(e) ? pc.green("✔") : pc.red("✘");
|
|
36926
|
+
getDefaultChannel().writeLine(` ${mark} ${e.model} ${pc.dim(e.providerUrl)} ${e.mmaVersion} ${e.certifiedAt.slice(0, 10)} ${e.suite.passed}/${e.suite.total} pass`);
|
|
36495
36927
|
}
|
|
36496
36928
|
}
|
|
36497
36929
|
async function uncertify(name, config, projectDir) {
|
|
@@ -36499,9 +36931,9 @@ async function uncertify(name, config, projectDir) {
|
|
|
36499
36931
|
projectDir
|
|
36500
36932
|
});
|
|
36501
36933
|
if (removed.global || removed.project)
|
|
36502
|
-
|
|
36934
|
+
getDefaultChannel().writeLine(t("cli.cert_uncertified", { model: name }));
|
|
36503
36935
|
else
|
|
36504
|
-
|
|
36936
|
+
getDefaultChannel().writeLine(t("cli.cert_not_found", { model: name }));
|
|
36505
36937
|
}
|
|
36506
36938
|
function summarize(results) {
|
|
36507
36939
|
return {
|
|
@@ -36514,19 +36946,19 @@ function summarize(results) {
|
|
|
36514
36946
|
function mergePartialResults(fresh, previous, rerunIds) {
|
|
36515
36947
|
const preserved = previous.filter((r) => !rerunIds.has(r.id));
|
|
36516
36948
|
if (preserved.length > 0) {
|
|
36517
|
-
|
|
36949
|
+
getDefaultChannel().writeLine(pc.dim(t("cli.cert_partial_merge", { kept: String(preserved.length) })));
|
|
36518
36950
|
}
|
|
36519
36951
|
return [...fresh, ...preserved];
|
|
36520
36952
|
}
|
|
36521
36953
|
function printResults(results) {
|
|
36522
36954
|
for (const r of results) {
|
|
36523
|
-
const icon = r.status === "pass" ?
|
|
36524
|
-
const detail = r.status === "skipped" ?
|
|
36525
|
-
|
|
36955
|
+
const icon = r.status === "pass" ? pc.green("✔") : r.status === "fail" ? pc.red("✘") : r.status === "skipped" ? pc.dim("–") : pc.yellow("!");
|
|
36956
|
+
const detail = r.status === "skipped" ? pc.dim(r.title) : `${r.passed}/${r.of}`;
|
|
36957
|
+
getDefaultChannel().writeLine(` ${icon} ${r.id} ${detail}`);
|
|
36526
36958
|
if (r.error)
|
|
36527
|
-
|
|
36959
|
+
getDefaultChannel().writeLine(` ${pc.dim(r.error)}`);
|
|
36528
36960
|
if (r.diagnostics)
|
|
36529
|
-
|
|
36961
|
+
getDefaultChannel().writeLine(r.diagnostics);
|
|
36530
36962
|
}
|
|
36531
36963
|
}
|
|
36532
36964
|
function writeReport(entry, projectDir) {
|
|
@@ -36553,10 +36985,10 @@ function writeReport(entry, projectDir) {
|
|
|
36553
36985
|
};
|
|
36554
36986
|
try {
|
|
36555
36987
|
writeFileSync23(reportPath, JSON.stringify(report, null, 2), "utf-8");
|
|
36556
|
-
|
|
36988
|
+
getDefaultChannel().writeLine(pc.dim(`
|
|
36557
36989
|
Report: ${reportPath}`));
|
|
36558
36990
|
} catch (e) {
|
|
36559
|
-
|
|
36991
|
+
getDefaultChannel().writeLine(pc.yellow(` Failed to write report: ${e.message}`), "stderr");
|
|
36560
36992
|
}
|
|
36561
36993
|
}
|
|
36562
36994
|
var HERE, MMA_ROOT;
|
|
@@ -36566,6 +36998,7 @@ var init_cli = __esm(() => {
|
|
|
36566
36998
|
init_loader3();
|
|
36567
36999
|
init_runner2();
|
|
36568
37000
|
init_manifest();
|
|
37001
|
+
init_output();
|
|
36569
37002
|
HERE = dirname22(fileURLToPath5(import.meta.url));
|
|
36570
37003
|
MMA_ROOT = findMmaRoot(HERE);
|
|
36571
37004
|
});
|
|
@@ -36603,7 +37036,7 @@ function registerBuiltinCommands(ctx) {
|
|
|
36603
37036
|
description: t("repl.clear"),
|
|
36604
37037
|
usage: t("repl.clear_usage"),
|
|
36605
37038
|
action: () => {
|
|
36606
|
-
|
|
37039
|
+
ctx.output.clearScreen();
|
|
36607
37040
|
}
|
|
36608
37041
|
});
|
|
36609
37042
|
}
|
|
@@ -36614,7 +37047,7 @@ function registerRunCommands(ctx) {
|
|
|
36614
37047
|
usage: t("repl.run_usage"),
|
|
36615
37048
|
action: async (args) => {
|
|
36616
37049
|
if (args.length === 0) {
|
|
36617
|
-
|
|
37050
|
+
ctx.output.writeLine(t("repl.run_usage"));
|
|
36618
37051
|
return;
|
|
36619
37052
|
}
|
|
36620
37053
|
const prompt = args.join(" ");
|
|
@@ -36629,7 +37062,7 @@ function registerRunCommands(ctx) {
|
|
|
36629
37062
|
action: async (args) => {
|
|
36630
37063
|
const source = args.join(" ");
|
|
36631
37064
|
if (!source) {
|
|
36632
|
-
|
|
37065
|
+
ctx.output.writeLine(t("repl.image_usage"));
|
|
36633
37066
|
return;
|
|
36634
37067
|
}
|
|
36635
37068
|
try {
|
|
@@ -36641,7 +37074,7 @@ function registerRunCommands(ctx) {
|
|
|
36641
37074
|
if (source.toLowerCase() === "clipboard") {
|
|
36642
37075
|
const clipBuf = await readClipboardImage2();
|
|
36643
37076
|
if (!clipBuf) {
|
|
36644
|
-
|
|
37077
|
+
ctx.output.writeLine(pc.yellow(t("image.clipboard_empty")));
|
|
36645
37078
|
return;
|
|
36646
37079
|
}
|
|
36647
37080
|
const { bufferToDataUrl: bufferToDataUrl2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
@@ -36655,7 +37088,7 @@ function registerRunCommands(ctx) {
|
|
|
36655
37088
|
} else {
|
|
36656
37089
|
const absPath = resolve24(process.cwd(), source);
|
|
36657
37090
|
if (!existsSync60(absPath)) {
|
|
36658
|
-
|
|
37091
|
+
ctx.output.writeLine(pc.red(t("image.not_found", { path: source })), "stderr");
|
|
36659
37092
|
return;
|
|
36660
37093
|
}
|
|
36661
37094
|
const result = await loadFileAsDataUrl2(absPath);
|
|
@@ -36664,7 +37097,7 @@ function registerRunCommands(ctx) {
|
|
|
36664
37097
|
}
|
|
36665
37098
|
const contextManager = ctx.agent.contextManager;
|
|
36666
37099
|
if (!contextManager) {
|
|
36667
|
-
|
|
37100
|
+
ctx.output.writeLine(pc.red(t("image.no_context")), "stderr");
|
|
36668
37101
|
return;
|
|
36669
37102
|
}
|
|
36670
37103
|
contextManager.addPendingImage({
|
|
@@ -36672,9 +37105,9 @@ function registerRunCommands(ctx) {
|
|
|
36672
37105
|
image_url: { url: dataUrl }
|
|
36673
37106
|
});
|
|
36674
37107
|
const sizeKb = Math.round(dataUrl.length * 3 / 4 / 1024);
|
|
36675
|
-
|
|
37108
|
+
ctx.output.writeLine(pc.green(t("image.attached", { source: label, size: `${sizeKb} KB` })));
|
|
36676
37109
|
} catch (err) {
|
|
36677
|
-
|
|
37110
|
+
ctx.output.writeLine(pc.red(t("image.error", { message: err.message })), "stderr");
|
|
36678
37111
|
}
|
|
36679
37112
|
}
|
|
36680
37113
|
});
|
|
@@ -36692,23 +37125,23 @@ function registerConfigCommands(ctx) {
|
|
|
36692
37125
|
const ctxW = cfg.contextWindow;
|
|
36693
37126
|
const sys = Math.floor(ctxW * cfg.contextBudget.systemPrompt);
|
|
36694
37127
|
const res = Math.floor(ctxW * cfg.contextBudget.responseReserve);
|
|
36695
|
-
|
|
37128
|
+
ctx.output.writeLine(`${t("repl.model")} ${cfg.model}`);
|
|
36696
37129
|
const providers = ctx.agent.listProviders();
|
|
36697
37130
|
const active = providers.find((p) => p.active);
|
|
36698
37131
|
if (active) {
|
|
36699
|
-
|
|
37132
|
+
ctx.output.writeLine(`${t("repl.provider")} ${active.label} (${pc.dim(active.type)}) → ${pc.dim(active.baseUrl)}`);
|
|
36700
37133
|
} else {
|
|
36701
|
-
|
|
36702
|
-
}
|
|
36703
|
-
|
|
36704
|
-
|
|
36705
|
-
|
|
36706
|
-
|
|
36707
|
-
|
|
36708
|
-
|
|
37134
|
+
ctx.output.writeLine(`${t("repl.provider")} ${cfg.provider.type} → ${cfg.provider.baseUrl}`);
|
|
37135
|
+
}
|
|
37136
|
+
ctx.output.writeLine(`${t("repl.context")} ${ctxW} (sys:${sys} res:${res} hist:${ctxW - sys - res})`);
|
|
37137
|
+
ctx.output.writeLine(`${t("repl.max_iters")} ${cfg.maxToolIterations}`);
|
|
37138
|
+
ctx.output.writeLine(`${t("repl.stuck_thresh")} ${cfg.stuckThreshold}`);
|
|
37139
|
+
ctx.output.writeLine(`${t("repl.reasoning_label")} ${cfg.showReasoning ? pc.green(t("repl.show")) : pc.dim(t("repl.hide"))}`);
|
|
37140
|
+
ctx.output.writeLine(`${t("repl.log_level")} ${cfg.logLevel}`);
|
|
37141
|
+
ctx.output.writeLine(`${t("repl.locale")} ${cfg.locale}`);
|
|
36709
37142
|
const meta = ctx.sessionManager?.getActiveMeta();
|
|
36710
37143
|
if (meta) {
|
|
36711
|
-
|
|
37144
|
+
ctx.output.writeLine(`${t("repl.session_label")} ${meta.name} (${meta.id}) — ${meta.messageCount} msgs`);
|
|
36712
37145
|
}
|
|
36713
37146
|
}
|
|
36714
37147
|
});
|
|
@@ -36721,13 +37154,13 @@ function registerConfigCommands(ctx) {
|
|
|
36721
37154
|
const VALID_LEVELS2 = ["auto", "none", "low", "medium", "high", "max"];
|
|
36722
37155
|
if (!level) {
|
|
36723
37156
|
ctx.config.showReasoning = !ctx.config.showReasoning;
|
|
36724
|
-
const status = ctx.config.showReasoning ?
|
|
36725
|
-
|
|
37157
|
+
const status = ctx.config.showReasoning ? pc.green(t("repl.show")) : pc.dim(t("repl.hide"));
|
|
37158
|
+
ctx.output.writeLine(t("repl.reasoning_status", { status }));
|
|
36726
37159
|
} else if (VALID_LEVELS2.includes(level)) {
|
|
36727
37160
|
ctx.agent.setReasoningLevel(level);
|
|
36728
|
-
|
|
37161
|
+
ctx.output.writeLine(pc.green(t("repl.reasoning_level_set", { level })));
|
|
36729
37162
|
} else {
|
|
36730
|
-
|
|
37163
|
+
ctx.output.writeLine(pc.yellow(t("repl.reasoning_invalid_level", { level, valid: VALID_LEVELS2.join(", ") })));
|
|
36731
37164
|
}
|
|
36732
37165
|
}
|
|
36733
37166
|
});
|
|
@@ -36738,15 +37171,15 @@ function registerConfigCommands(ctx) {
|
|
|
36738
37171
|
action: () => {
|
|
36739
37172
|
const providers = ctx.agent.listProviders();
|
|
36740
37173
|
const active = providers.find((p) => p.active);
|
|
36741
|
-
|
|
37174
|
+
ctx.output.writeLine(`${t("repl.model")} ${ctx.config.model}`);
|
|
36742
37175
|
if (active) {
|
|
36743
|
-
|
|
37176
|
+
ctx.output.writeLine(`${t("repl.provider")} ${active.label} (${pc.dim(active.type)}) @ ${pc.dim(active.baseUrl)}`);
|
|
36744
37177
|
} else {
|
|
36745
|
-
|
|
37178
|
+
ctx.output.writeLine(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
|
|
36746
37179
|
}
|
|
36747
37180
|
const meta = ctx.sessionManager?.getActiveMeta();
|
|
36748
37181
|
if (meta) {
|
|
36749
|
-
|
|
37182
|
+
ctx.output.writeLine(`${t("repl.session_label")} ${meta.name} (${meta.id}) — ${meta.messageCount} messages`);
|
|
36750
37183
|
}
|
|
36751
37184
|
}
|
|
36752
37185
|
});
|
|
@@ -36756,7 +37189,7 @@ function registerConfigCommands(ctx) {
|
|
|
36756
37189
|
aliases: ["setup"],
|
|
36757
37190
|
usage: t("repl.wizard_usage"),
|
|
36758
37191
|
action: async () => {
|
|
36759
|
-
|
|
37192
|
+
ctx.output.writeLine(pc.yellow(t("repl.wizard_running")));
|
|
36760
37193
|
await ctx.withExclusiveInput(async () => {
|
|
36761
37194
|
const answers = await runSetup(ctx.rl);
|
|
36762
37195
|
const configPath = join54(ctx.configDir, "config.json");
|
|
@@ -36769,7 +37202,7 @@ function registerConfigCommands(ctx) {
|
|
|
36769
37202
|
ctx.config.locale = answers.locale;
|
|
36770
37203
|
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
36771
37204
|
await ctx.agent.reconfigure(ctx.config);
|
|
36772
|
-
|
|
37205
|
+
ctx.output.writeLine(pc.green(t("cli.config_saved")));
|
|
36773
37206
|
});
|
|
36774
37207
|
}
|
|
36775
37208
|
});
|
|
@@ -36779,17 +37212,17 @@ function registerConfigCommands(ctx) {
|
|
|
36779
37212
|
usage: t("repl.sysprompt_desc"),
|
|
36780
37213
|
action: () => {
|
|
36781
37214
|
const info = ctx.agent.getSystemPromptInfo();
|
|
36782
|
-
|
|
36783
|
-
|
|
37215
|
+
ctx.output.writeLine(pc.bold(t("repl.sysprompt_tokens", { count: String(info.tokenCount) })));
|
|
37216
|
+
ctx.output.writeLine(pc.dim("─".repeat(60)));
|
|
36784
37217
|
for (const line of info.text.split(`
|
|
36785
37218
|
`)) {
|
|
36786
|
-
|
|
37219
|
+
ctx.output.writeLine(line);
|
|
36787
37220
|
}
|
|
36788
|
-
|
|
37221
|
+
ctx.output.writeLine(pc.dim("─".repeat(60)));
|
|
36789
37222
|
if (info.excluded.length > 0) {
|
|
36790
|
-
|
|
37223
|
+
ctx.output.writeLine(pc.yellow(t("repl.excluded_blocks", { count: String(info.excluded.length) })));
|
|
36791
37224
|
for (const e of info.excluded) {
|
|
36792
|
-
|
|
37225
|
+
ctx.output.writeLine(pc.dim(` - ${e.slice(0, 80)}${e.length > 80 ? "..." : ""}`));
|
|
36793
37226
|
}
|
|
36794
37227
|
}
|
|
36795
37228
|
}
|
|
@@ -36801,13 +37234,13 @@ function registerConfigCommands(ctx) {
|
|
|
36801
37234
|
action: async (args) => {
|
|
36802
37235
|
const indexer = ctx.agent.getModule("indexer");
|
|
36803
37236
|
if (!indexer) {
|
|
36804
|
-
|
|
37237
|
+
ctx.output.writeLine(pc.yellow(t("indexer.not_indexed")));
|
|
36805
37238
|
return;
|
|
36806
37239
|
}
|
|
36807
37240
|
const action = args[0] || "summary";
|
|
36808
37241
|
const query = args.slice(1).join(" ");
|
|
36809
37242
|
const result = await runMapAction(indexer, action, query);
|
|
36810
|
-
|
|
37243
|
+
ctx.output.writeLine(result.output);
|
|
36811
37244
|
}
|
|
36812
37245
|
});
|
|
36813
37246
|
}
|
|
@@ -36815,28 +37248,28 @@ function registerProviderCommands(ctx) {
|
|
|
36815
37248
|
const list = () => {
|
|
36816
37249
|
const providers = ctx.agent.listProviders();
|
|
36817
37250
|
if (providers.length === 0) {
|
|
36818
|
-
|
|
36819
|
-
|
|
37251
|
+
ctx.output.writeLine(`${t("repl.provider_current")} ${ctx.config.provider.type}`);
|
|
37252
|
+
ctx.output.writeLine(` ${ctx.config.provider.baseUrl}`);
|
|
36820
37253
|
return;
|
|
36821
37254
|
}
|
|
36822
|
-
|
|
37255
|
+
ctx.output.writeLine(t("repl.provider_current"));
|
|
36823
37256
|
for (const p of providers) {
|
|
36824
|
-
const marker = p.active ?
|
|
36825
|
-
|
|
37257
|
+
const marker = p.active ? pc.green("* ") : " ";
|
|
37258
|
+
ctx.output.writeLine(` ${marker}${p.label} (${pc.dim(p.type)}) ${pc.dim(p.baseUrl)}`);
|
|
36826
37259
|
}
|
|
36827
37260
|
};
|
|
36828
37261
|
const use = async (args) => {
|
|
36829
37262
|
const name = args[0];
|
|
36830
37263
|
if (!name) {
|
|
36831
|
-
|
|
37264
|
+
ctx.output.writeLine(t("repl.provider_usage"));
|
|
36832
37265
|
return;
|
|
36833
37266
|
}
|
|
36834
37267
|
try {
|
|
36835
37268
|
await ctx.agent.setProvider(name);
|
|
36836
37269
|
ctx.refreshModelCache();
|
|
36837
|
-
|
|
37270
|
+
ctx.output.writeLine(pc.green(t("repl.provider_set", { name })));
|
|
36838
37271
|
} catch (e) {
|
|
36839
|
-
|
|
37272
|
+
ctx.output.writeLine(pc.red(e.message), "stderr");
|
|
36840
37273
|
}
|
|
36841
37274
|
};
|
|
36842
37275
|
const add = async (args) => {
|
|
@@ -36847,7 +37280,7 @@ function registerProviderCommands(ctx) {
|
|
|
36847
37280
|
if (arg.startsWith("--")) {
|
|
36848
37281
|
const value = args[i + 1];
|
|
36849
37282
|
if (value === undefined || value.startsWith("--")) {
|
|
36850
|
-
|
|
37283
|
+
ctx.output.writeLine(pc.red(t("repl.provider_add_missing_value", { flag: arg })), "stderr");
|
|
36851
37284
|
return;
|
|
36852
37285
|
}
|
|
36853
37286
|
flags[arg.slice(2)] = value;
|
|
@@ -36857,7 +37290,7 @@ function registerProviderCommands(ctx) {
|
|
|
36857
37290
|
}
|
|
36858
37291
|
}
|
|
36859
37292
|
if (!name) {
|
|
36860
|
-
|
|
37293
|
+
ctx.output.writeLine(t("repl.provider_usage"));
|
|
36861
37294
|
return;
|
|
36862
37295
|
}
|
|
36863
37296
|
const entries = Array.isArray(ctx.config.provider.entries) ? ctx.config.provider.entries : [];
|
|
@@ -36871,7 +37304,7 @@ function registerProviderCommands(ctx) {
|
|
|
36871
37304
|
}
|
|
36872
37305
|
const baseUrl = flags.url || HOSTED_BASE_URLS[name] || HOSTED_BASE_URLS[`opencode-${name}`] || "";
|
|
36873
37306
|
if (!baseUrl) {
|
|
36874
|
-
|
|
37307
|
+
ctx.output.writeLine(pc.red(t("cli.provider_no_url", { name })), "stderr");
|
|
36875
37308
|
return;
|
|
36876
37309
|
}
|
|
36877
37310
|
entries.push({
|
|
@@ -36893,8 +37326,8 @@ function registerProviderCommands(ctx) {
|
|
|
36893
37326
|
const configPath = join54(ctx.configDir, "config.json");
|
|
36894
37327
|
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
36895
37328
|
await ctx.agent.reconfigure(ctx.config);
|
|
36896
|
-
|
|
36897
|
-
|
|
37329
|
+
ctx.output.writeLine(pc.green(t("cli.provider_added", { name })));
|
|
37330
|
+
ctx.output.writeLine(t("repl.provider_switch_hint", { name }));
|
|
36898
37331
|
};
|
|
36899
37332
|
const handlers = {
|
|
36900
37333
|
list,
|
|
@@ -36909,14 +37342,14 @@ function registerProviderCommands(ctx) {
|
|
|
36909
37342
|
const subcmd = args[0];
|
|
36910
37343
|
const handler = subcmd ? handlers[subcmd] : handlers.list;
|
|
36911
37344
|
if (!handler) {
|
|
36912
|
-
|
|
37345
|
+
ctx.output.writeLine(t("repl.provider_usage"));
|
|
36913
37346
|
return;
|
|
36914
37347
|
}
|
|
36915
37348
|
await handler(args.slice(1));
|
|
36916
37349
|
}
|
|
36917
37350
|
});
|
|
36918
37351
|
const listModels = async () => {
|
|
36919
|
-
|
|
37352
|
+
ctx.output.writeLine(`${t("repl.model_current")} ${ctx.config.model}`);
|
|
36920
37353
|
const { OpenAICompatProvider: OpenAICompatProvider2 } = await Promise.resolve().then(() => (init_openai_compat(), exports_openai_compat));
|
|
36921
37354
|
const provider = new OpenAICompatProvider2({
|
|
36922
37355
|
model: ctx.config.model,
|
|
@@ -36925,42 +37358,42 @@ function registerProviderCommands(ctx) {
|
|
|
36925
37358
|
contextWindow: ctx.config.contextWindow
|
|
36926
37359
|
});
|
|
36927
37360
|
const { Spinner: Spinner2 } = await Promise.resolve().then(() => (init_spinner(), exports_spinner));
|
|
36928
|
-
const s = new Spinner2;
|
|
37361
|
+
const s = new Spinner2({ channel: ctx.output });
|
|
36929
37362
|
s.start(t("cli.fetching_models"));
|
|
36930
37363
|
try {
|
|
36931
37364
|
const models = await provider.listModels();
|
|
36932
37365
|
s.stop();
|
|
36933
37366
|
if (models.length > 0) {
|
|
36934
37367
|
ctx.refreshModelCache();
|
|
36935
|
-
|
|
37368
|
+
ctx.output.writeLine(t("cli.available_models"));
|
|
36936
37369
|
const { getCertMark: getCertMark2 } = await Promise.resolve().then(() => (init_manifest(), exports_manifest));
|
|
36937
37370
|
for (const m of models) {
|
|
36938
|
-
const marker = m === ctx.config.model ?
|
|
37371
|
+
const marker = m === ctx.config.model ? pc.green("* ") : " ";
|
|
36939
37372
|
const mark = getCertMark2(m, ctx.config.provider.baseUrl, version2, process.cwd());
|
|
36940
|
-
const cert = mark === "certified" ?
|
|
36941
|
-
const label = mark === "certified" ? ` ${
|
|
36942
|
-
|
|
37373
|
+
const cert = mark === "certified" ? pc.green("✔") : mark === "stale" ? pc.yellow("○") : pc.dim("·");
|
|
37374
|
+
const label = mark === "certified" ? ` ${pc.green(t("cli.cert_label"))}` : mark === "stale" ? ` ${pc.yellow(t("cli.cert_stale_label"))}` : "";
|
|
37375
|
+
ctx.output.writeLine(` ${marker}${cert} ${m}${label}`);
|
|
36943
37376
|
}
|
|
36944
37377
|
} else {
|
|
36945
|
-
|
|
37378
|
+
ctx.output.writeLine(t("cli.no_models_found"));
|
|
36946
37379
|
}
|
|
36947
37380
|
} catch (err) {
|
|
36948
37381
|
s.stop();
|
|
36949
|
-
|
|
37382
|
+
ctx.output.writeLine(t("cli.model_fetch_failed", { error: String(err) }), "stderr");
|
|
36950
37383
|
}
|
|
36951
|
-
|
|
37384
|
+
ctx.output.writeLine(t("cli.model_hint"));
|
|
36952
37385
|
};
|
|
36953
37386
|
const useModel = async (args) => {
|
|
36954
37387
|
const name = args[0];
|
|
36955
37388
|
if (!name) {
|
|
36956
|
-
|
|
37389
|
+
ctx.output.writeLine(t("repl.model_usage"));
|
|
36957
37390
|
return;
|
|
36958
37391
|
}
|
|
36959
37392
|
ctx.config.model = name;
|
|
36960
37393
|
const configPath = join54(ctx.configDir, "config.json");
|
|
36961
37394
|
saveConfig(ctx.config, configPath, dirname24(configPath));
|
|
36962
37395
|
await ctx.agent.reconfigure(ctx.config);
|
|
36963
|
-
|
|
37396
|
+
ctx.output.writeLine(pc.green(t("repl.model_set", { name })));
|
|
36964
37397
|
};
|
|
36965
37398
|
const modelHandlers = {
|
|
36966
37399
|
list: listModels,
|
|
@@ -36974,7 +37407,7 @@ function registerProviderCommands(ctx) {
|
|
|
36974
37407
|
const subcmd = args[0];
|
|
36975
37408
|
const handler = subcmd ? modelHandlers[subcmd] : modelHandlers.list;
|
|
36976
37409
|
if (!handler) {
|
|
36977
|
-
|
|
37410
|
+
ctx.output.writeLine(t("repl.model_usage"));
|
|
36978
37411
|
return;
|
|
36979
37412
|
}
|
|
36980
37413
|
await handler(args.slice(1));
|
|
@@ -36992,29 +37425,29 @@ function registerProviderCommands(ctx) {
|
|
|
36992
37425
|
};
|
|
36993
37426
|
if (args.length === 0) {
|
|
36994
37427
|
for (const line of budgetBreakdownLines(ctx.config))
|
|
36995
|
-
|
|
36996
|
-
|
|
37428
|
+
ctx.output.writeLine(line);
|
|
37429
|
+
ctx.output.writeLine(pc.dim(t("repl.context_usage")));
|
|
36997
37430
|
return;
|
|
36998
37431
|
}
|
|
36999
37432
|
if (args[0] === "system" || args[0] === "reserve") {
|
|
37000
37433
|
const key = args[0];
|
|
37001
37434
|
const value = Number(args[1]);
|
|
37002
37435
|
if (setBudgetShare(ctx.config, key, value) !== null) {
|
|
37003
|
-
|
|
37436
|
+
ctx.output.writeLine(pc.yellow(t("cli.context_invalid_fraction")));
|
|
37004
37437
|
return;
|
|
37005
37438
|
}
|
|
37006
37439
|
await save();
|
|
37007
|
-
|
|
37440
|
+
ctx.output.writeLine(pc.green(t("cli.context_fraction_set", { key, value })));
|
|
37008
37441
|
return;
|
|
37009
37442
|
}
|
|
37010
37443
|
const size = parseInt(args[0], 10);
|
|
37011
37444
|
if (isNaN(size) || size < 1024) {
|
|
37012
|
-
|
|
37445
|
+
ctx.output.writeLine(t("cli.invalid_context_size"));
|
|
37013
37446
|
return;
|
|
37014
37447
|
}
|
|
37015
37448
|
ctx.config.contextWindow = size;
|
|
37016
37449
|
await save();
|
|
37017
|
-
|
|
37450
|
+
ctx.output.writeLine(pc.green(t("cli.context_set", { size })));
|
|
37018
37451
|
}
|
|
37019
37452
|
});
|
|
37020
37453
|
}
|
|
@@ -37024,12 +37457,12 @@ function registerAgentCommands(ctx) {
|
|
|
37024
37457
|
description: t("repl.reload"),
|
|
37025
37458
|
usage: t("repl.reload_usage"),
|
|
37026
37459
|
action: async () => {
|
|
37027
|
-
|
|
37460
|
+
ctx.output.writeLine(pc.yellow(t("repl.reloading")));
|
|
37028
37461
|
await ctx.reload();
|
|
37029
|
-
|
|
37030
|
-
|
|
37031
|
-
|
|
37032
|
-
|
|
37462
|
+
ctx.output.writeLine(pc.green(t("repl.reloaded")));
|
|
37463
|
+
ctx.output.writeLine(`${t("repl.model")} ${ctx.config.model}`);
|
|
37464
|
+
ctx.output.writeLine(`${t("repl.context")} ${ctx.config.contextWindow}`);
|
|
37465
|
+
ctx.output.writeLine(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
|
|
37033
37466
|
}
|
|
37034
37467
|
});
|
|
37035
37468
|
ctx.registerCommand({
|
|
@@ -37038,18 +37471,18 @@ function registerAgentCommands(ctx) {
|
|
|
37038
37471
|
usage: t("repl.plugins_usage"),
|
|
37039
37472
|
action: (args) => {
|
|
37040
37473
|
if (!ctx.pluginManager) {
|
|
37041
|
-
|
|
37474
|
+
ctx.output.writeLine(t("cli.plugins.none"));
|
|
37042
37475
|
return;
|
|
37043
37476
|
}
|
|
37044
37477
|
const showAll = args.includes("--all");
|
|
37045
37478
|
const infos = ctx.pluginManager.getPluginInfos();
|
|
37046
37479
|
const filtered = showAll ? infos : infos.filter(({ plugin: plugin3 }) => !plugin3.isBuiltin);
|
|
37047
37480
|
if (filtered.length === 0) {
|
|
37048
|
-
|
|
37481
|
+
ctx.output.writeLine(t("cli.plugins.none"));
|
|
37049
37482
|
return;
|
|
37050
37483
|
}
|
|
37051
37484
|
const mmaVersion = version2;
|
|
37052
|
-
|
|
37485
|
+
ctx.output.writeLine(t("cli.plugins.header", {
|
|
37053
37486
|
count: String(filtered.length),
|
|
37054
37487
|
mma: mmaVersion
|
|
37055
37488
|
}));
|
|
@@ -37057,12 +37490,12 @@ function registerAgentCommands(ctx) {
|
|
|
37057
37490
|
const v = plugin3.version || "-";
|
|
37058
37491
|
const origin = source || "builtin";
|
|
37059
37492
|
const mark = plugin3.isBuiltin ? t("cli.plugins.builtin_mark") : " ";
|
|
37060
|
-
|
|
37493
|
+
ctx.output.writeLine(` ${mark} ${plugin3.name} v${v} [${origin}]`);
|
|
37061
37494
|
}
|
|
37062
37495
|
if (!showAll) {
|
|
37063
37496
|
const builtinCount = infos.filter(({ plugin: plugin3 }) => plugin3.isBuiltin).length;
|
|
37064
37497
|
if (builtinCount > 0) {
|
|
37065
|
-
|
|
37498
|
+
ctx.output.writeLine(pc.dim(` (${builtinCount} builtin hidden — /plugins --all to show)`));
|
|
37066
37499
|
}
|
|
37067
37500
|
}
|
|
37068
37501
|
}
|
|
@@ -37077,7 +37510,7 @@ function registerLspCommands(ctx) {
|
|
|
37077
37510
|
const subcommand = args[0] || "status";
|
|
37078
37511
|
const lspModule = ctx.agent.getModule("lsp");
|
|
37079
37512
|
if (!lspModule) {
|
|
37080
|
-
|
|
37513
|
+
ctx.output.writeLine(pc.yellow(t("repl.lsp_not_available")));
|
|
37081
37514
|
return;
|
|
37082
37515
|
}
|
|
37083
37516
|
switch (subcommand) {
|
|
@@ -37085,49 +37518,47 @@ function registerLspCommands(ctx) {
|
|
|
37085
37518
|
const disabled = lspModule.getDisabledServers();
|
|
37086
37519
|
const failures = lspModule.getFailureCounts();
|
|
37087
37520
|
const config = ctx.config.lsp;
|
|
37088
|
-
|
|
37089
|
-
|
|
37521
|
+
ctx.output.writeLine(pc.bold(t("repl.lsp_status_header")));
|
|
37522
|
+
ctx.output.writeLine(`${t("repl.lsp_enabled")} ${config?.enabled ? pc.green("yes") : pc.red("no")}`);
|
|
37090
37523
|
if (disabled.length > 0) {
|
|
37091
|
-
|
|
37524
|
+
ctx.output.writeLine(pc.yellow(`${t("repl.lsp_disabled_servers")} ${disabled.join(", ")}`));
|
|
37092
37525
|
}
|
|
37093
37526
|
if (failures.size > 0) {
|
|
37094
|
-
|
|
37527
|
+
ctx.output.writeLine(pc.dim(t("repl.lsp_failure_counts")));
|
|
37095
37528
|
for (const [server, count] of failures) {
|
|
37096
|
-
|
|
37529
|
+
ctx.output.writeLine(pc.dim(` ${server}: ${count}`));
|
|
37097
37530
|
}
|
|
37098
37531
|
}
|
|
37099
37532
|
if (disabled.length === 0 && failures.size === 0) {
|
|
37100
|
-
|
|
37533
|
+
ctx.output.writeLine(pc.green(t("repl.lsp_all_ok")));
|
|
37101
37534
|
}
|
|
37102
37535
|
break;
|
|
37103
37536
|
}
|
|
37104
37537
|
case "restart": {
|
|
37105
|
-
|
|
37538
|
+
ctx.output.writeLine(pc.yellow(t("repl.lsp_restarting")));
|
|
37106
37539
|
lspModule.resetDisabledServers();
|
|
37107
|
-
|
|
37540
|
+
ctx.output.writeLine(pc.green(t("repl.lsp_restarted")));
|
|
37108
37541
|
break;
|
|
37109
37542
|
}
|
|
37110
37543
|
case "check": {
|
|
37111
37544
|
const path = args[1];
|
|
37112
37545
|
if (!path) {
|
|
37113
|
-
|
|
37546
|
+
ctx.output.writeLine(pc.yellow(t("repl.lsp_check_usage")));
|
|
37114
37547
|
return;
|
|
37115
37548
|
}
|
|
37116
|
-
|
|
37549
|
+
ctx.output.writeLine(pc.dim(t("repl.lsp_checking", { path })));
|
|
37117
37550
|
try {
|
|
37118
37551
|
const result = await ctx.agent.runTool("lsp_check", { path });
|
|
37119
37552
|
if (result?.output) {
|
|
37120
|
-
|
|
37553
|
+
ctx.output.writeLine(result.output);
|
|
37121
37554
|
}
|
|
37122
37555
|
} catch (e) {
|
|
37123
|
-
|
|
37124
|
-
error: errMsg(e)
|
|
37125
|
-
})));
|
|
37556
|
+
ctx.output.writeLine(pc.red(t("repl.lsp_check_error", { error: errMsg(e) })), "stderr");
|
|
37126
37557
|
}
|
|
37127
37558
|
break;
|
|
37128
37559
|
}
|
|
37129
37560
|
default: {
|
|
37130
|
-
|
|
37561
|
+
ctx.output.writeLine(pc.dim(t("repl.lsp_usage")));
|
|
37131
37562
|
break;
|
|
37132
37563
|
}
|
|
37133
37564
|
}
|
|
@@ -37153,11 +37584,11 @@ function registerSessionCommands(ctx) {
|
|
|
37153
37584
|
const sessions = ctx.sessionManager.list();
|
|
37154
37585
|
const active = ctx.sessionManager.getActive();
|
|
37155
37586
|
if (sessions.length === 0) {
|
|
37156
|
-
|
|
37587
|
+
ctx.output.writeLine(t("session.no_sessions_hint"));
|
|
37157
37588
|
return;
|
|
37158
37589
|
}
|
|
37159
37590
|
const rows = sessions.map((s) => [
|
|
37160
|
-
s.id === active ?
|
|
37591
|
+
s.id === active ? pc.green("●") : "",
|
|
37161
37592
|
s.id.slice(0, 12),
|
|
37162
37593
|
s.name,
|
|
37163
37594
|
s.updatedAt.slice(0, 19).replace("T", " "),
|
|
@@ -37170,9 +37601,9 @@ function registerSessionCommands(ctx) {
|
|
|
37170
37601
|
t("session.col_updated"),
|
|
37171
37602
|
t("session.col_msgs")
|
|
37172
37603
|
], rows)) {
|
|
37173
|
-
|
|
37604
|
+
ctx.output.writeLine(line);
|
|
37174
37605
|
}
|
|
37175
|
-
|
|
37606
|
+
ctx.output.writeLine(pc.dim(`
|
|
37176
37607
|
${t("repl.resume_hint")}`));
|
|
37177
37608
|
}
|
|
37178
37609
|
});
|
|
@@ -37185,9 +37616,9 @@ function registerSessionCommands(ctx) {
|
|
|
37185
37616
|
const name = args.join(" ") || undefined;
|
|
37186
37617
|
const meta = ctx.sessionManager.create(name);
|
|
37187
37618
|
ctx.agent.clearContext();
|
|
37188
|
-
|
|
37189
|
-
|
|
37190
|
-
|
|
37619
|
+
ctx.output.clearScreen();
|
|
37620
|
+
ctx.output.writeLine(`${t("session.created", { name: meta.name })} (${pc.dim(meta.id.slice(0, 12))})`);
|
|
37621
|
+
ctx.output.writeLine(pc.dim(` ${t("session.chat_cleared")}
|
|
37191
37622
|
`));
|
|
37192
37623
|
}
|
|
37193
37624
|
});
|
|
@@ -37200,46 +37631,46 @@ function registerSessionCommands(ctx) {
|
|
|
37200
37631
|
const query = args.join(" ");
|
|
37201
37632
|
const sessions = ctx.sessionManager.list();
|
|
37202
37633
|
if (!query) {
|
|
37203
|
-
|
|
37634
|
+
ctx.output.writeLine(pc.dim(t("session.available")));
|
|
37204
37635
|
const active = ctx.sessionManager.getActive();
|
|
37205
37636
|
for (const s of sessions) {
|
|
37206
|
-
const marker = s.id === active ?
|
|
37207
|
-
|
|
37637
|
+
const marker = s.id === active ? pc.green(" *") : " ";
|
|
37638
|
+
ctx.output.writeLine(pc.dim(` ${marker} ${s.id.slice(0, 12)} ${s.name}`));
|
|
37208
37639
|
}
|
|
37209
|
-
|
|
37640
|
+
ctx.output.writeLine(pc.dim(`
|
|
37210
37641
|
${t("repl.resume_usage")}`));
|
|
37211
37642
|
return;
|
|
37212
37643
|
}
|
|
37213
37644
|
const match = sessions.find((s) => s.id === query || s.id.startsWith(query) || s.name.toLowerCase().includes(query.toLowerCase()));
|
|
37214
37645
|
if (!match) {
|
|
37215
|
-
|
|
37646
|
+
ctx.output.writeLine(t("session.no_match", { query }));
|
|
37216
37647
|
return;
|
|
37217
37648
|
}
|
|
37218
37649
|
ctx.sessionManager.setActive(match.id);
|
|
37219
37650
|
const history = ctx.sessionManager.loadHistory();
|
|
37220
37651
|
ctx.agent.setContext(history);
|
|
37221
|
-
|
|
37222
|
-
|
|
37223
|
-
|
|
37652
|
+
ctx.output.clearScreen();
|
|
37653
|
+
ctx.output.writeLine(pc.bold(pc.green(t("session.resumed", { name: match.name }))) + " " + pc.dim(`(${match.id.slice(0, 12)})`) + " — " + match.messageCount + " " + t("repl.msgs"));
|
|
37654
|
+
ctx.output.writeLine(pc.dim("─".repeat(50)));
|
|
37224
37655
|
if (history.length === 0) {
|
|
37225
|
-
|
|
37656
|
+
ctx.output.writeLine(pc.dim(t("session.no_history")));
|
|
37226
37657
|
} else {
|
|
37227
|
-
|
|
37228
|
-
|
|
37658
|
+
ctx.output.writeLine(pc.dim(t("session.chat_history")));
|
|
37659
|
+
ctx.output.writeLine("");
|
|
37229
37660
|
for (const msg of history) {
|
|
37230
37661
|
if (msg.role === "user") {
|
|
37231
|
-
|
|
37232
|
-
|
|
37233
|
-
|
|
37662
|
+
ctx.output.writeLine(pc.cyan(t("session.user_label") + ":"));
|
|
37663
|
+
ctx.output.writeLine(getMessageText(msg.content));
|
|
37664
|
+
ctx.output.writeLine("");
|
|
37234
37665
|
} else if (msg.role === "assistant") {
|
|
37235
|
-
|
|
37236
|
-
|
|
37237
|
-
|
|
37666
|
+
ctx.output.writeLine(pc.green(t("session.assistant_label") + ":"));
|
|
37667
|
+
ctx.output.writeLine(getMessageText(msg.content));
|
|
37668
|
+
ctx.output.writeLine("");
|
|
37238
37669
|
}
|
|
37239
37670
|
}
|
|
37240
37671
|
}
|
|
37241
|
-
|
|
37242
|
-
|
|
37672
|
+
ctx.output.writeLine(pc.dim("─".repeat(50)));
|
|
37673
|
+
ctx.output.writeLine(pc.dim(` ${t("session.chat_loaded")}`));
|
|
37243
37674
|
}
|
|
37244
37675
|
});
|
|
37245
37676
|
ctx.registerCommand({
|
|
@@ -37249,16 +37680,16 @@ function registerSessionCommands(ctx) {
|
|
|
37249
37680
|
action: (args) => {
|
|
37250
37681
|
const name = args.join(" ");
|
|
37251
37682
|
if (!name) {
|
|
37252
|
-
|
|
37683
|
+
ctx.output.writeLine(t("repl.rename_usage"));
|
|
37253
37684
|
return;
|
|
37254
37685
|
}
|
|
37255
37686
|
const active = ctx.sessionManager.getActive();
|
|
37256
37687
|
if (!active) {
|
|
37257
|
-
|
|
37688
|
+
ctx.output.writeLine(t("session.no_active"));
|
|
37258
37689
|
return;
|
|
37259
37690
|
}
|
|
37260
37691
|
ctx.sessionManager.rename(active, name);
|
|
37261
|
-
|
|
37692
|
+
ctx.output.writeLine(t("session.renamed", { name }));
|
|
37262
37693
|
}
|
|
37263
37694
|
});
|
|
37264
37695
|
ctx.registerCommand({
|
|
@@ -37269,17 +37700,17 @@ function registerSessionCommands(ctx) {
|
|
|
37269
37700
|
action: (args) => {
|
|
37270
37701
|
const query = args[0];
|
|
37271
37702
|
if (!query) {
|
|
37272
|
-
|
|
37703
|
+
ctx.output.writeLine(t("repl.delete_usage"));
|
|
37273
37704
|
return;
|
|
37274
37705
|
}
|
|
37275
37706
|
const sessions = ctx.sessionManager.list();
|
|
37276
37707
|
const match = sessions.find((s) => s.id === query || s.id.startsWith(query));
|
|
37277
37708
|
if (!match) {
|
|
37278
|
-
|
|
37709
|
+
ctx.output.writeLine(t("session.no_match", { query }));
|
|
37279
37710
|
return;
|
|
37280
37711
|
}
|
|
37281
37712
|
ctx.sessionManager.delete(match.id);
|
|
37282
|
-
|
|
37713
|
+
ctx.output.writeLine(`${t("session.deleted", { id: match.id })}: ${match.name}`);
|
|
37283
37714
|
}
|
|
37284
37715
|
});
|
|
37285
37716
|
}
|
|
@@ -37289,72 +37720,72 @@ function registerSkillCommands(ctx) {
|
|
|
37289
37720
|
const listSkills = () => {
|
|
37290
37721
|
const available = ctx.skillsModule.getAvailable();
|
|
37291
37722
|
if (available.length === 0) {
|
|
37292
|
-
|
|
37723
|
+
ctx.output.writeLine(t("repl.no_skills"));
|
|
37293
37724
|
return;
|
|
37294
37725
|
}
|
|
37295
|
-
|
|
37726
|
+
ctx.output.writeLine(pc.bold(t("repl.available_skills")));
|
|
37296
37727
|
for (const skill of available) {
|
|
37297
37728
|
const tokens = estimateTokens(skill.content);
|
|
37298
37729
|
const loaded = ctx.skillsModule.getLoaded().some((s) => s.name === skill.name);
|
|
37299
|
-
const marker = loaded ?
|
|
37300
|
-
|
|
37730
|
+
const marker = loaded ? pc.green(" [loaded]") : "";
|
|
37731
|
+
ctx.output.writeLine(` ${pc.cyan(skill.name)}${marker} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
|
|
37301
37732
|
}
|
|
37302
37733
|
};
|
|
37303
37734
|
const listLoaded = () => {
|
|
37304
37735
|
const loaded = ctx.skillsModule.getLoaded();
|
|
37305
37736
|
const budget = ctx.skillsModule.getBudget();
|
|
37306
37737
|
if (loaded.length === 0) {
|
|
37307
|
-
|
|
37738
|
+
ctx.output.writeLine(t("repl.no_loaded"));
|
|
37308
37739
|
return;
|
|
37309
37740
|
}
|
|
37310
|
-
|
|
37741
|
+
ctx.output.writeLine(pc.bold(t("repl.loaded_skills")));
|
|
37311
37742
|
for (const skill of loaded) {
|
|
37312
37743
|
const tokens = estimateTokens(skill.content);
|
|
37313
|
-
|
|
37744
|
+
ctx.output.writeLine(` ${pc.cyan(skill.name)} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
|
|
37314
37745
|
}
|
|
37315
|
-
|
|
37746
|
+
ctx.output.writeLine(pc.dim(`
|
|
37316
37747
|
${t("repl.budget", { used: budget.used, total: budget.total, remaining: budget.remaining })}`));
|
|
37317
37748
|
};
|
|
37318
37749
|
const loadSkill = (args) => {
|
|
37319
37750
|
const arg = args.join(" ");
|
|
37320
37751
|
if (!arg) {
|
|
37321
|
-
|
|
37752
|
+
ctx.output.writeLine(t("repl.skill_load_usage"));
|
|
37322
37753
|
return;
|
|
37323
37754
|
}
|
|
37324
37755
|
const result = ctx.skillsModule.loadByName(arg);
|
|
37325
37756
|
if (result.success) {
|
|
37326
|
-
|
|
37757
|
+
ctx.output.writeLine(pc.green(result.message));
|
|
37327
37758
|
} else {
|
|
37328
|
-
|
|
37759
|
+
ctx.output.writeLine(pc.red(result.message), "stderr");
|
|
37329
37760
|
}
|
|
37330
37761
|
};
|
|
37331
37762
|
const unloadSkill = (args) => {
|
|
37332
37763
|
const arg = args.join(" ");
|
|
37333
37764
|
if (!arg) {
|
|
37334
|
-
|
|
37765
|
+
ctx.output.writeLine(t("repl.skill_unload_usage"));
|
|
37335
37766
|
return;
|
|
37336
37767
|
}
|
|
37337
37768
|
if (ctx.skillsModule.unload(arg)) {
|
|
37338
|
-
|
|
37769
|
+
ctx.output.writeLine(pc.green(t("repl.skill_unloaded", { name: arg })));
|
|
37339
37770
|
} else {
|
|
37340
|
-
|
|
37771
|
+
ctx.output.writeLine(pc.red(t("repl.skill_not_loaded", { name: arg })), "stderr");
|
|
37341
37772
|
}
|
|
37342
37773
|
};
|
|
37343
37774
|
const searchSkills = (args) => {
|
|
37344
37775
|
const arg = args.join(" ");
|
|
37345
37776
|
if (!arg) {
|
|
37346
|
-
|
|
37777
|
+
ctx.output.writeLine(t("repl.skill_search_usage"));
|
|
37347
37778
|
return;
|
|
37348
37779
|
}
|
|
37349
37780
|
const results = ctx.skillsModule.search(arg);
|
|
37350
37781
|
if (results.length === 0) {
|
|
37351
|
-
|
|
37782
|
+
ctx.output.writeLine(t("repl.no_skill_match", { query: arg }));
|
|
37352
37783
|
return;
|
|
37353
37784
|
}
|
|
37354
|
-
|
|
37785
|
+
ctx.output.writeLine(pc.bold(t("repl.skills_matching", { query: arg })));
|
|
37355
37786
|
for (const skill of results) {
|
|
37356
37787
|
const tokens = estimateTokens(skill.content);
|
|
37357
|
-
|
|
37788
|
+
ctx.output.writeLine(` ${pc.cyan(skill.name)} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
|
|
37358
37789
|
}
|
|
37359
37790
|
};
|
|
37360
37791
|
const skillHandlers = {
|
|
@@ -37372,8 +37803,8 @@ function registerSkillCommands(ctx) {
|
|
|
37372
37803
|
const subcmd = args[0];
|
|
37373
37804
|
const handler = subcmd ? skillHandlers[subcmd] : skillHandlers.list;
|
|
37374
37805
|
if (!handler) {
|
|
37375
|
-
|
|
37376
|
-
|
|
37806
|
+
ctx.output.writeLine(pc.red(t("repl.skill_unknown_sub", { subcmd })), "stderr");
|
|
37807
|
+
ctx.output.writeLine(t("repl.skill_usage"));
|
|
37377
37808
|
return;
|
|
37378
37809
|
}
|
|
37379
37810
|
handler(args.slice(1));
|
|
@@ -37386,20 +37817,20 @@ async function runConfigMigrate(ctx) {
|
|
|
37386
37817
|
const configDir = ctx.configDir;
|
|
37387
37818
|
const configPath = join54(configDir, "config.json");
|
|
37388
37819
|
if (hasDomainFiles3(configDir)) {
|
|
37389
|
-
|
|
37820
|
+
ctx.output.writeLine(pc.yellow(t("config.migrate_no_legacy")));
|
|
37390
37821
|
return;
|
|
37391
37822
|
}
|
|
37392
37823
|
if (!existsSync59(configPath)) {
|
|
37393
|
-
|
|
37824
|
+
ctx.output.writeLine(pc.yellow(t("config.migrate_no_legacy")));
|
|
37394
37825
|
return;
|
|
37395
37826
|
}
|
|
37396
|
-
|
|
37827
|
+
ctx.output.writeLine(t("config.migrate_start"));
|
|
37397
37828
|
const { config } = loadCfg({ configDir, projectConfigPath: join54(configDir, ".mmrc") });
|
|
37398
37829
|
saveConfig(config, configPath, configDir);
|
|
37399
37830
|
const { renameSync: renameSync4, readdirSync: readdirSync19 } = await import("fs");
|
|
37400
37831
|
renameSync4(configPath, configPath + ".bak");
|
|
37401
37832
|
const domainFiles = readdirSync19(join54(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
37402
|
-
|
|
37833
|
+
ctx.output.writeLine(pc.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
37403
37834
|
}
|
|
37404
37835
|
var version2, COMMAND_GROUPS;
|
|
37405
37836
|
var init_repl_commands = __esm(() => {
|
|
@@ -37948,6 +38379,7 @@ function applySecurityPolicy(preset, customOverrides) {
|
|
|
37948
38379
|
// src/cli/security-commands.ts
|
|
37949
38380
|
init_audit_notifier();
|
|
37950
38381
|
init_i18n();
|
|
38382
|
+
init_output();
|
|
37951
38383
|
function toggleSessionEncryption(security, enabled2) {
|
|
37952
38384
|
const enc = security.sessionEncryption ?? {};
|
|
37953
38385
|
enc.enabled = enabled2;
|
|
@@ -37972,28 +38404,28 @@ function createSecurityCommand(program2) {
|
|
|
37972
38404
|
const rateLimits = security.rateLimits || {};
|
|
37973
38405
|
const sessionEncryption = security.sessionEncryption || {};
|
|
37974
38406
|
const auditNotifier = security.auditNotifier || {};
|
|
37975
|
-
|
|
37976
|
-
|
|
37977
|
-
|
|
37978
|
-
|
|
37979
|
-
|
|
37980
|
-
|
|
37981
|
-
|
|
37982
|
-
|
|
37983
|
-
|
|
37984
|
-
|
|
38407
|
+
getDefaultChannel().writeLine(t("cli.security.current_policy"));
|
|
38408
|
+
getDefaultChannel().writeLine(` ${t("cli.security.bash_enabled")}: ${bash.blacklist?.length > 0 ? t("cli.yes") : t("cli.no")}`);
|
|
38409
|
+
getDefaultChannel().writeLine(` ${t("cli.security.path_validation")}: ${paths.denied?.length > 0 ? t("cli.yes") : t("cli.no")}`);
|
|
38410
|
+
getDefaultChannel().writeLine(` ${t("cli.security.network_validation")}: ${network.deniedDomains?.length > 0 || network.allowedDomains?.length > 0 ? t("cli.yes") : t("cli.no")}`);
|
|
38411
|
+
getDefaultChannel().writeLine(` ${t("cli.security.content_scanning")}: ${contentScan.enabled ? t("cli.yes") : t("cli.no")}`);
|
|
38412
|
+
getDefaultChannel().writeLine(` ${t("cli.security.max_recursion")}: ${security.maxRecursionDepth ?? 3}`);
|
|
38413
|
+
getDefaultChannel().writeLine(` ${t("cli.security.max_file_ops")}: ${security.maxFileOperations ?? 100}`);
|
|
38414
|
+
getDefaultChannel().writeLine(` ${t("cli.security.rate_limit")}: ${rateLimits.maxRequestsPerMinute ?? 60}/min`);
|
|
38415
|
+
getDefaultChannel().writeLine(` ${t("cli.security.session_encryption")}: ${sessionEncryption.enabled ? t("cli.yes") : t("cli.no")}`);
|
|
38416
|
+
getDefaultChannel().writeLine(` ${t("cli.security.audit_notifier")}: ${auditNotifier.enabled ? t("cli.yes") : t("cli.no")}`);
|
|
37985
38417
|
});
|
|
37986
38418
|
securityCmd.command("policies").description(t("cli.security.policies")).action(async () => {
|
|
37987
|
-
|
|
37988
|
-
|
|
38419
|
+
getDefaultChannel().writeLine(t("cli.security.available_policies"));
|
|
38420
|
+
getDefaultChannel().writeLine("");
|
|
37989
38421
|
for (const [preset, policy] of Object.entries(SECURITY_POLICIES)) {
|
|
37990
38422
|
if (preset === "custom")
|
|
37991
38423
|
continue;
|
|
37992
38424
|
const marker = " ";
|
|
37993
|
-
|
|
37994
|
-
|
|
37995
|
-
|
|
37996
|
-
|
|
38425
|
+
getDefaultChannel().writeLine(` ${marker}${preset.padEnd(12)} ${policy.name}`);
|
|
38426
|
+
getDefaultChannel().writeLine(` ${policy.description}`);
|
|
38427
|
+
getDefaultChannel().writeLine(` ${t("cli.security.recommended_for")}: ${policy.recommendedFor.join(", ")}`);
|
|
38428
|
+
getDefaultChannel().writeLine("");
|
|
37997
38429
|
}
|
|
37998
38430
|
});
|
|
37999
38431
|
securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
|
|
@@ -38001,15 +38433,15 @@ function createSecurityCommand(program2) {
|
|
|
38001
38433
|
const { config: appConfig } = await bootstrap();
|
|
38002
38434
|
const validPresets = ["strict", "balanced", "permissive"];
|
|
38003
38435
|
if (!validPresets.includes(preset)) {
|
|
38004
|
-
|
|
38436
|
+
getDefaultChannel().writeLine(t("cli.security.invalid_preset", { presets: validPresets.join(", ") }));
|
|
38005
38437
|
return;
|
|
38006
38438
|
}
|
|
38007
38439
|
const policy = getSecurityPolicy(preset);
|
|
38008
38440
|
const newSecurityConfig = applySecurityPolicy(preset);
|
|
38009
38441
|
appConfig.security = newSecurityConfig;
|
|
38010
38442
|
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
38011
|
-
|
|
38012
|
-
|
|
38443
|
+
getDefaultChannel().writeLine(t("cli.security.policy_applied", { name: policy.name }));
|
|
38444
|
+
getDefaultChannel().writeLine(t("cli.security.policy_description", { description: policy.description }));
|
|
38013
38445
|
});
|
|
38014
38446
|
securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
|
|
38015
38447
|
const configPath = join47(homedir16(), ".mma", "config.json");
|
|
@@ -38017,7 +38449,7 @@ function createSecurityCommand(program2) {
|
|
|
38017
38449
|
const security = appConfig.security = appConfig.security || {};
|
|
38018
38450
|
toggleSessionEncryption(security, true);
|
|
38019
38451
|
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
38020
|
-
|
|
38452
|
+
getDefaultChannel().writeLine(t("cli.security.encryption_enabled"));
|
|
38021
38453
|
});
|
|
38022
38454
|
securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
|
|
38023
38455
|
const configPath = join47(homedir16(), ".mma", "config.json");
|
|
@@ -38025,7 +38457,7 @@ function createSecurityCommand(program2) {
|
|
|
38025
38457
|
const security = appConfig.security = appConfig.security || {};
|
|
38026
38458
|
toggleSessionEncryption(security, false);
|
|
38027
38459
|
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
38028
|
-
|
|
38460
|
+
getDefaultChannel().writeLine(t("cli.security.encryption_disabled"));
|
|
38029
38461
|
});
|
|
38030
38462
|
securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
|
|
38031
38463
|
const configPath = join47(homedir16(), ".mma", "config.json");
|
|
@@ -38033,7 +38465,7 @@ function createSecurityCommand(program2) {
|
|
|
38033
38465
|
const security = appConfig.security = appConfig.security || {};
|
|
38034
38466
|
toggleAuditNotifier(security, true);
|
|
38035
38467
|
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
38036
|
-
|
|
38468
|
+
getDefaultChannel().writeLine(t("cli.security.audit_enabled"));
|
|
38037
38469
|
});
|
|
38038
38470
|
securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
|
|
38039
38471
|
const configPath = join47(homedir16(), ".mma", "config.json");
|
|
@@ -38041,23 +38473,23 @@ function createSecurityCommand(program2) {
|
|
|
38041
38473
|
const security = appConfig.security = appConfig.security || {};
|
|
38042
38474
|
toggleAuditNotifier(security, false);
|
|
38043
38475
|
saveConfig(appConfig, configPath, dirname19(configPath));
|
|
38044
|
-
|
|
38476
|
+
getDefaultChannel().writeLine(t("cli.security.audit_disabled"));
|
|
38045
38477
|
});
|
|
38046
38478
|
securityCmd.command("audit-stats").description(t("cli.security.audit_stats")).action(async () => {
|
|
38047
38479
|
const stats = globalAuditNotifier.getStats();
|
|
38048
|
-
|
|
38049
|
-
|
|
38050
|
-
|
|
38051
|
-
|
|
38052
|
-
|
|
38053
|
-
|
|
38054
|
-
|
|
38055
|
-
|
|
38056
|
-
|
|
38057
|
-
|
|
38480
|
+
getDefaultChannel().writeLine(t("cli.security.audit_stats_title"));
|
|
38481
|
+
getDefaultChannel().writeLine(` ${t("cli.security.total_notifications")}: ${stats.total}`);
|
|
38482
|
+
getDefaultChannel().writeLine("");
|
|
38483
|
+
getDefaultChannel().writeLine(t("cli.security.by_severity"));
|
|
38484
|
+
getDefaultChannel().writeLine(` ${t("cli.security.low")}: ${stats.bySeverity.low}`);
|
|
38485
|
+
getDefaultChannel().writeLine(` ${t("cli.security.medium")}: ${stats.bySeverity.medium}`);
|
|
38486
|
+
getDefaultChannel().writeLine(` ${t("cli.security.high")}: ${stats.bySeverity.high}`);
|
|
38487
|
+
getDefaultChannel().writeLine(` ${t("cli.security.critical")}: ${stats.bySeverity.critical}`);
|
|
38488
|
+
getDefaultChannel().writeLine("");
|
|
38489
|
+
getDefaultChannel().writeLine(t("cli.security.by_type"));
|
|
38058
38490
|
for (const [type2, count] of Object.entries(stats.byType)) {
|
|
38059
38491
|
if (count > 0) {
|
|
38060
|
-
|
|
38492
|
+
getDefaultChannel().writeLine(` ${type2}: ${count}`);
|
|
38061
38493
|
}
|
|
38062
38494
|
}
|
|
38063
38495
|
});
|
|
@@ -38067,6 +38499,7 @@ function createSecurityCommand(program2) {
|
|
|
38067
38499
|
init_bootstrap();
|
|
38068
38500
|
init_version();
|
|
38069
38501
|
init_i18n();
|
|
38502
|
+
init_output();
|
|
38070
38503
|
function createPluginCommand(program2) {
|
|
38071
38504
|
const pluginsCmd = program2.command("plugins").description(t("cli.plugins.description"));
|
|
38072
38505
|
pluginsCmd.command("list").description(t("cli.plugins.list")).option("-a, --all", t("cli.plugins.all")).action(async (cmdOpts) => {
|
|
@@ -38077,19 +38510,19 @@ function createPluginCommand(program2) {
|
|
|
38077
38510
|
infos = infos.filter(({ plugin: plugin3 }) => !plugin3.isBuiltin);
|
|
38078
38511
|
}
|
|
38079
38512
|
if (infos.length === 0) {
|
|
38080
|
-
|
|
38513
|
+
getDefaultChannel().writeLine(t("cli.plugins.none"));
|
|
38081
38514
|
return;
|
|
38082
38515
|
}
|
|
38083
38516
|
const mmaVersion = readMmaVersion();
|
|
38084
|
-
|
|
38517
|
+
getDefaultChannel().writeLine(t("cli.plugins.header", { count: String(infos.length), mma: mmaVersion }));
|
|
38085
38518
|
for (const { plugin: plugin3, source } of infos) {
|
|
38086
38519
|
const version = plugin3.version || "-";
|
|
38087
38520
|
const origin = source || "builtin";
|
|
38088
38521
|
const builtin = plugin3.isBuiltin ? t("cli.plugins.builtin_mark") : " ";
|
|
38089
|
-
|
|
38522
|
+
getDefaultChannel().writeLine(` ${builtin} ${plugin3.name} v${version} [${origin}]`);
|
|
38090
38523
|
}
|
|
38091
38524
|
if (!all) {
|
|
38092
|
-
|
|
38525
|
+
getDefaultChannel().writeLine(t("cli.plugins.only_external"));
|
|
38093
38526
|
}
|
|
38094
38527
|
});
|
|
38095
38528
|
}
|
|
@@ -38280,6 +38713,7 @@ function extractLatestChangelog(changelog) {
|
|
|
38280
38713
|
}
|
|
38281
38714
|
|
|
38282
38715
|
// src/cli/commands.ts
|
|
38716
|
+
init_output();
|
|
38283
38717
|
var version = readMmaVersion();
|
|
38284
38718
|
function buildInitCommand(program2) {
|
|
38285
38719
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
@@ -38325,7 +38759,7 @@ function buildInitCommand(program2) {
|
|
|
38325
38759
|
}
|
|
38326
38760
|
}
|
|
38327
38761
|
saveConfig(config, configPath, dirname23(configPath));
|
|
38328
|
-
|
|
38762
|
+
getDefaultChannel().writeLine(t("cli.config_saved"));
|
|
38329
38763
|
});
|
|
38330
38764
|
}
|
|
38331
38765
|
function buildConfigCommands(program2) {
|
|
@@ -38352,11 +38786,11 @@ function buildConfigCommands(program2) {
|
|
|
38352
38786
|
else
|
|
38353
38787
|
obj[lastKey] = value;
|
|
38354
38788
|
saveConfig(config, configPath, dirname23(configPath));
|
|
38355
|
-
|
|
38789
|
+
getDefaultChannel().writeLine(t("cli.set_done", { key, value }));
|
|
38356
38790
|
});
|
|
38357
38791
|
configCmd.command("show").description(t("cli.show_config")).action(async () => {
|
|
38358
38792
|
const { config } = await bootstrap();
|
|
38359
|
-
|
|
38793
|
+
writeMachineJson(config);
|
|
38360
38794
|
});
|
|
38361
38795
|
configCmd.command("migrate").description(t("cli.migrate_config")).action(async () => {
|
|
38362
38796
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
@@ -38364,14 +38798,14 @@ function buildConfigCommands(program2) {
|
|
|
38364
38798
|
const configDir = join53(homedir17(), ".mma");
|
|
38365
38799
|
const configPath = join53(configDir, "config.json");
|
|
38366
38800
|
if (hasDomainFiles3(configDir)) {
|
|
38367
|
-
|
|
38801
|
+
getDefaultChannel().writeLine(pc.yellow(t("config.migrate_no_legacy")));
|
|
38368
38802
|
return;
|
|
38369
38803
|
}
|
|
38370
38804
|
if (!existsSync58(configPath)) {
|
|
38371
|
-
|
|
38805
|
+
getDefaultChannel().writeLine(pc.yellow(t("config.migrate_no_legacy")));
|
|
38372
38806
|
return;
|
|
38373
38807
|
}
|
|
38374
|
-
|
|
38808
|
+
getDefaultChannel().writeLine(t("config.migrate_start"));
|
|
38375
38809
|
const { config } = loadConfig2({ configDir, projectConfigPath: join53(configDir, ".mmrc") });
|
|
38376
38810
|
saveConfig(config, configPath, configDir);
|
|
38377
38811
|
const bakPath = configPath + ".bak";
|
|
@@ -38379,14 +38813,14 @@ function buildConfigCommands(program2) {
|
|
|
38379
38813
|
renameSync4(configPath, bakPath);
|
|
38380
38814
|
const { readdirSync: readdirSync19 } = await import("fs");
|
|
38381
38815
|
const domainFiles = readdirSync19(join53(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
38382
|
-
|
|
38816
|
+
getDefaultChannel().writeLine(pc.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
38383
38817
|
});
|
|
38384
38818
|
}
|
|
38385
38819
|
function buildModelCommands(program2) {
|
|
38386
38820
|
const model = program2.command("model").description(t("cli.manage_models"));
|
|
38387
38821
|
model.command("list").description(t("cli.list_models")).action(async () => {
|
|
38388
38822
|
const { config } = await bootstrap();
|
|
38389
|
-
|
|
38823
|
+
getDefaultChannel().writeLine(`${t("cli.current_model")} ${config.model}`);
|
|
38390
38824
|
const { createProvider: createProvider2 } = await Promise.resolve().then(() => (init_create(), exports_create));
|
|
38391
38825
|
const provider = createProvider2(config.provider.type, {
|
|
38392
38826
|
model: config.model,
|
|
@@ -38401,30 +38835,30 @@ function buildModelCommands(program2) {
|
|
|
38401
38835
|
const models = await provider.listModels();
|
|
38402
38836
|
s.stop();
|
|
38403
38837
|
if (models.length > 0) {
|
|
38404
|
-
|
|
38838
|
+
getDefaultChannel().writeLine(t("cli.available_models"));
|
|
38405
38839
|
const { getCertMark: getCertMark2 } = await Promise.resolve().then(() => (init_manifest(), exports_manifest));
|
|
38406
38840
|
for (const m of models) {
|
|
38407
38841
|
const marker = m === config.model ? "* " : " ";
|
|
38408
38842
|
const mark = getCertMark2(m, config.provider.baseUrl, version, process.cwd());
|
|
38409
38843
|
const cert = mark === "certified" ? "✔" : mark === "stale" ? "○" : "·";
|
|
38410
|
-
const label = mark === "certified" ? ` ${
|
|
38411
|
-
|
|
38844
|
+
const label = mark === "certified" ? ` ${pc.green(t("cli.cert_label"))}` : mark === "stale" ? ` ${pc.yellow(t("cli.cert_stale_label"))}` : "";
|
|
38845
|
+
getDefaultChannel().writeLine(` ${marker}${cert} ${m}${label}`);
|
|
38412
38846
|
}
|
|
38413
38847
|
} else {
|
|
38414
|
-
|
|
38848
|
+
getDefaultChannel().writeLine(t("cli.no_models_found"));
|
|
38415
38849
|
}
|
|
38416
38850
|
} catch (err) {
|
|
38417
38851
|
s.stop();
|
|
38418
|
-
|
|
38852
|
+
getDefaultChannel().writeLine(t("cli.model_fetch_failed", { error: String(err) }));
|
|
38419
38853
|
}
|
|
38420
|
-
|
|
38854
|
+
getDefaultChannel().writeLine(t("cli.model_hint"));
|
|
38421
38855
|
});
|
|
38422
38856
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
38423
38857
|
const configPath = join53(homedir17(), ".mma", "config.json");
|
|
38424
38858
|
const { config } = await bootstrap();
|
|
38425
38859
|
config.model = name;
|
|
38426
38860
|
saveConfig(config, configPath, dirname23(configPath));
|
|
38427
|
-
|
|
38861
|
+
getDefaultChannel().writeLine(t("cli.model_set", { name }));
|
|
38428
38862
|
});
|
|
38429
38863
|
model.command("certify").argument("<name>", "Model name").option("--provider-url <url>", t("cli.cert_provider_url")).option("--provider-key <key>", t("cli.cert_provider_key")).option("--context-window <n>", t("cli.cert_context_window")).option("--tags <tags>", t("cli.cert_tags"), "core").option("--scenarios <ids>", t("cli.cert_scenarios")).option("--timeout <ms>", t("cli.cert_timeout")).option("--reps <n>", t("cli.cert_reps")).option("--force", t("cli.cert_force")).option("--clean", t("cli.cert_clean")).description(t("cli.certify")).action(async (name, cmdOpts) => {
|
|
38430
38864
|
const { config } = await bootstrap();
|
|
@@ -38467,26 +38901,26 @@ function buildContextCommand(program2) {
|
|
|
38467
38901
|
const key = opts.system !== undefined ? "system" : "reserve";
|
|
38468
38902
|
const value = Number(opts.system ?? opts.reserve);
|
|
38469
38903
|
if (setBudgetShare(config, key, value) !== null) {
|
|
38470
|
-
|
|
38904
|
+
getDefaultChannel().writeLine(t("cli.context_invalid_fraction"));
|
|
38471
38905
|
return;
|
|
38472
38906
|
}
|
|
38473
38907
|
saveConfig(config, configPath, dirname23(configPath));
|
|
38474
|
-
|
|
38908
|
+
getDefaultChannel().writeLine(t("cli.context_fraction_set", { key, value }));
|
|
38475
38909
|
return;
|
|
38476
38910
|
}
|
|
38477
38911
|
if (size === undefined) {
|
|
38478
38912
|
for (const line of budgetBreakdownLines(config))
|
|
38479
|
-
|
|
38913
|
+
getDefaultChannel().writeLine(line);
|
|
38480
38914
|
return;
|
|
38481
38915
|
}
|
|
38482
38916
|
const contextWindow = parseInt(size, 10);
|
|
38483
38917
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
38484
|
-
|
|
38918
|
+
getDefaultChannel().writeLine(t("cli.invalid_context_size"));
|
|
38485
38919
|
return;
|
|
38486
38920
|
}
|
|
38487
38921
|
config.contextWindow = contextWindow;
|
|
38488
38922
|
saveConfig(config, configPath, dirname23(configPath));
|
|
38489
|
-
|
|
38923
|
+
getDefaultChannel().writeLine(t("cli.context_set", { size: contextWindow }));
|
|
38490
38924
|
});
|
|
38491
38925
|
}
|
|
38492
38926
|
function buildUsageCommand(program2) {
|
|
@@ -38497,43 +38931,43 @@ function buildUsageCommand(program2) {
|
|
|
38497
38931
|
log: (level, message) => level === "warn" ? logger4.warn(message) : logger4.debug(message)
|
|
38498
38932
|
});
|
|
38499
38933
|
if (result.reason === "unsupported") {
|
|
38500
|
-
|
|
38934
|
+
getDefaultChannel().writeLine(t("cli.usage_unsupported", { provider }));
|
|
38501
38935
|
return;
|
|
38502
38936
|
}
|
|
38503
38937
|
if (result.reason === "no-key") {
|
|
38504
|
-
|
|
38938
|
+
getDefaultChannel().writeLine(t("cli.usage_no_key"));
|
|
38505
38939
|
return;
|
|
38506
38940
|
}
|
|
38507
38941
|
if (result.reason === "error" || !result.budget) {
|
|
38508
|
-
|
|
38942
|
+
getDefaultChannel().writeLine(t("cli.usage_error", { error: result.error ?? "" }));
|
|
38509
38943
|
return;
|
|
38510
38944
|
}
|
|
38511
38945
|
const b = result.budget;
|
|
38512
38946
|
let printed = false;
|
|
38513
38947
|
if (b.keyUsageUsd !== undefined) {
|
|
38514
|
-
|
|
38948
|
+
getDefaultChannel().writeLine(t("cli.usage_key_usage", { usage: formatCost(b.keyUsageUsd) }));
|
|
38515
38949
|
printed = true;
|
|
38516
38950
|
}
|
|
38517
38951
|
if (b.keyLimitUsd !== undefined && b.keyRemainingUsd !== undefined) {
|
|
38518
|
-
|
|
38952
|
+
getDefaultChannel().writeLine(t("cli.usage_key_limit", {
|
|
38519
38953
|
limit: formatCost(b.keyLimitUsd),
|
|
38520
38954
|
remaining: formatCost(b.keyRemainingUsd)
|
|
38521
38955
|
}));
|
|
38522
38956
|
printed = true;
|
|
38523
38957
|
}
|
|
38524
38958
|
if (b.balanceUsd !== undefined) {
|
|
38525
|
-
|
|
38959
|
+
getDefaultChannel().writeLine(t("cli.usage_balance", { balance: formatCost(b.balanceUsd) }));
|
|
38526
38960
|
printed = true;
|
|
38527
38961
|
}
|
|
38528
38962
|
if (b.totalCreditsUsd !== undefined && b.totalUsageUsd !== undefined) {
|
|
38529
|
-
|
|
38963
|
+
getDefaultChannel().writeLine(t("cli.usage_account", {
|
|
38530
38964
|
credits: formatCost(b.totalCreditsUsd),
|
|
38531
38965
|
used: formatCost(b.totalUsageUsd)
|
|
38532
38966
|
}));
|
|
38533
38967
|
printed = true;
|
|
38534
38968
|
}
|
|
38535
38969
|
if (!printed)
|
|
38536
|
-
|
|
38970
|
+
getDefaultChannel().writeLine(t("cli.usage_empty"));
|
|
38537
38971
|
});
|
|
38538
38972
|
}
|
|
38539
38973
|
function buildMapCommand(program2) {
|
|
@@ -38541,11 +38975,11 @@ function buildMapCommand(program2) {
|
|
|
38541
38975
|
const { agent } = await bootstrap();
|
|
38542
38976
|
const indexer = agent.getModule("indexer");
|
|
38543
38977
|
if (!indexer) {
|
|
38544
|
-
|
|
38978
|
+
getDefaultChannel().writeLine(t("indexer.not_indexed"));
|
|
38545
38979
|
return;
|
|
38546
38980
|
}
|
|
38547
38981
|
const result = await runMapAction(indexer, action, query);
|
|
38548
|
-
|
|
38982
|
+
getDefaultChannel().writeLine(result.output);
|
|
38549
38983
|
});
|
|
38550
38984
|
}
|
|
38551
38985
|
function buildProviderCommands(program2) {
|
|
@@ -38563,25 +38997,25 @@ function buildProviderCommands(program2) {
|
|
|
38563
38997
|
timeoutMs: opts.timeout ? Number(opts.timeout) : 5000
|
|
38564
38998
|
});
|
|
38565
38999
|
for (const r of results) {
|
|
38566
|
-
const mark = r.ok ?
|
|
38567
|
-
const detail = r.ok ?
|
|
38568
|
-
|
|
39000
|
+
const mark = r.ok ? pc.green("✓") : pc.red("✗");
|
|
39001
|
+
const detail = r.ok ? pc.dim(`${r.ms}ms, ${r.models} models`) : pc.red(r.error ?? "failed");
|
|
39002
|
+
getDefaultChannel().writeLine(` ${mark} ${r.name.padEnd(16)} ${detail}`);
|
|
38569
39003
|
}
|
|
38570
39004
|
});
|
|
38571
39005
|
provider.command("list").description(t("cli.list_providers")).action(async () => {
|
|
38572
39006
|
const { config, agent } = await bootstrap();
|
|
38573
39007
|
const providers = agent.listProviders();
|
|
38574
39008
|
if (providers.length > 0) {
|
|
38575
|
-
|
|
39009
|
+
getDefaultChannel().writeLine(t("cli.current_provider"));
|
|
38576
39010
|
for (const p of providers) {
|
|
38577
|
-
const marker = p.active ?
|
|
38578
|
-
const prio = p.priority !== undefined ? ` ${
|
|
38579
|
-
|
|
39011
|
+
const marker = p.active ? pc.green("* ") : " ";
|
|
39012
|
+
const prio = p.priority !== undefined ? ` ${pc.dim(`prio=${p.priority}`)}` : "";
|
|
39013
|
+
getDefaultChannel().writeLine(` ${marker}${p.label} (${pc.dim(p.type)}) ${pc.dim(p.baseUrl)}${prio}`);
|
|
38580
39014
|
}
|
|
38581
39015
|
return;
|
|
38582
39016
|
}
|
|
38583
|
-
|
|
38584
|
-
|
|
39017
|
+
getDefaultChannel().writeLine(`${t("cli.current_provider")} ${config.provider.type}`);
|
|
39018
|
+
getDefaultChannel().writeLine(`${t("cli.base_url")} ${config.provider.baseUrl}`);
|
|
38585
39019
|
});
|
|
38586
39020
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
38587
39021
|
const configPath = join53(homedir17(), ".mma", "config.json");
|
|
@@ -38589,9 +39023,9 @@ function buildProviderCommands(program2) {
|
|
|
38589
39023
|
if (config.provider.entries && config.provider.entries.length > 0) {
|
|
38590
39024
|
try {
|
|
38591
39025
|
await agent.setProvider(name);
|
|
38592
|
-
|
|
39026
|
+
getDefaultChannel().writeLine(t("cli.provider_set", { name }));
|
|
38593
39027
|
} catch (e) {
|
|
38594
|
-
|
|
39028
|
+
getDefaultChannel().writeLine(pc.red(e.message));
|
|
38595
39029
|
}
|
|
38596
39030
|
return;
|
|
38597
39031
|
}
|
|
@@ -38601,9 +39035,9 @@ function buildProviderCommands(program2) {
|
|
|
38601
39035
|
config.provider.baseUrl = baseUrl;
|
|
38602
39036
|
}
|
|
38603
39037
|
saveConfig(config, configPath, dirname23(configPath));
|
|
38604
|
-
|
|
39038
|
+
getDefaultChannel().writeLine(t("cli.provider_set", { name }));
|
|
38605
39039
|
if (baseUrl) {
|
|
38606
|
-
|
|
39040
|
+
getDefaultChannel().writeLine(t("cli.provider_base_hint", { baseUrl }));
|
|
38607
39041
|
}
|
|
38608
39042
|
});
|
|
38609
39043
|
provider.command("add").argument("<name>", "Provider type or label").option("--url <url>", "Base URL").option("--key <key>", "API key").option("--priority <n>", "Fallback priority (lower = tried first)").option("--context-window <n>", "Context window override for this entry").option("--rpm <n>", "Max requests per minute for this entry").option("--parallel <n>", "Max parallel tasks for this entry").description(t("cli.add_provider")).action(async (name, opts) => {
|
|
@@ -38620,7 +39054,7 @@ function buildProviderCommands(program2) {
|
|
|
38620
39054
|
}
|
|
38621
39055
|
const baseUrl = opts.url || HOSTED_BASE_URLS[name] || HOSTED_BASE_URLS[`opencode-${name}`] || "";
|
|
38622
39056
|
if (!baseUrl) {
|
|
38623
|
-
|
|
39057
|
+
getDefaultChannel().writeLine(pc.red(t("cli.provider_no_url", { name })));
|
|
38624
39058
|
return;
|
|
38625
39059
|
}
|
|
38626
39060
|
entries.push({
|
|
@@ -38640,8 +39074,8 @@ function buildProviderCommands(program2) {
|
|
|
38640
39074
|
config.provider.entries = entries;
|
|
38641
39075
|
config.provider.active = config.provider.active || config.provider.type;
|
|
38642
39076
|
saveConfig(config, configPath, dirname23(configPath));
|
|
38643
|
-
|
|
38644
|
-
|
|
39077
|
+
getDefaultChannel().writeLine(pc.green(t("cli.provider_added", { name })));
|
|
39078
|
+
getDefaultChannel().writeLine(t("cli.provider_switch_hint"));
|
|
38645
39079
|
});
|
|
38646
39080
|
}
|
|
38647
39081
|
function buildSessionCommands(program2) {
|
|
@@ -38650,45 +39084,45 @@ function buildSessionCommands(program2) {
|
|
|
38650
39084
|
const { sessionManager } = await bootstrap();
|
|
38651
39085
|
const sessions = sessionManager.list();
|
|
38652
39086
|
if (sessions.length === 0) {
|
|
38653
|
-
|
|
39087
|
+
getDefaultChannel().writeLine(t("session.no_sessions"));
|
|
38654
39088
|
return;
|
|
38655
39089
|
}
|
|
38656
39090
|
const active = sessionManager.getActive();
|
|
38657
39091
|
for (const s of sessions) {
|
|
38658
39092
|
const marker = s.id === active ? "*" : " ";
|
|
38659
|
-
|
|
39093
|
+
getDefaultChannel().writeLine(` ${marker} ${s.id.slice(0, 12)} ${s.name} ${s.messageCount} msgs ${s.updatedAt.slice(0, 10)}`);
|
|
38660
39094
|
}
|
|
38661
39095
|
});
|
|
38662
39096
|
session2.command("show").argument("<id>", "Session id").description(t("cli.show_details")).action(async (id) => {
|
|
38663
39097
|
const { sessionManager } = await bootstrap();
|
|
38664
39098
|
const meta = sessionManager.get(id);
|
|
38665
39099
|
if (!meta) {
|
|
38666
|
-
|
|
39100
|
+
getDefaultChannel().writeLine(t("session.not_found", { id }));
|
|
38667
39101
|
return;
|
|
38668
39102
|
}
|
|
38669
|
-
|
|
38670
|
-
|
|
38671
|
-
|
|
38672
|
-
|
|
38673
|
-
|
|
38674
|
-
|
|
38675
|
-
|
|
38676
|
-
|
|
39103
|
+
getDefaultChannel().writeLine(`ID: ${meta.id}`);
|
|
39104
|
+
getDefaultChannel().writeLine(`Name: ${meta.name}`);
|
|
39105
|
+
getDefaultChannel().writeLine(`Created: ${meta.createdAt}`);
|
|
39106
|
+
getDefaultChannel().writeLine(`Updated: ${meta.updatedAt}`);
|
|
39107
|
+
getDefaultChannel().writeLine(`Messages: ${meta.messageCount}`);
|
|
39108
|
+
getDefaultChannel().writeLine(`Model: ${meta.model}`);
|
|
39109
|
+
getDefaultChannel().writeLine(`Context: ${meta.contextWindow}`);
|
|
39110
|
+
getDefaultChannel().writeLine(`Project: ${meta.projectDir}`);
|
|
38677
39111
|
const moeEvents = sessionManager.loadSessionLog(id).filter((e) => e.type.startsWith("moe_"));
|
|
38678
39112
|
if (moeEvents.length > 0) {
|
|
38679
|
-
|
|
38680
|
-
|
|
39113
|
+
getDefaultChannel().writeLine("");
|
|
39114
|
+
getDefaultChannel().writeLine(pc.cyan("MoE events:"));
|
|
38681
39115
|
for (const e of moeEvents) {
|
|
38682
39116
|
const ts = e.ts.slice(11, 19);
|
|
38683
39117
|
if (e.type === "moe_subtask") {
|
|
38684
|
-
|
|
39118
|
+
getDefaultChannel().writeLine(` ${pc.dim(ts)} [subtask] ${e.subtaskId} (${e.expertTag}) ${e.status ?? ""}${e.durationMs !== undefined ? ` ${e.durationMs}ms` : ""}`);
|
|
38685
39119
|
} else if (e.type === "moe_plan") {
|
|
38686
|
-
|
|
39120
|
+
getDefaultChannel().writeLine(` ${pc.dim(ts)} [plan] ${e.status === "ok" ? e.subtaskIds?.join(", ") : e.status}`);
|
|
38687
39121
|
} else if (e.type === "moe_replan") {
|
|
38688
|
-
|
|
39122
|
+
getDefaultChannel().writeLine(` ${pc.dim(ts)} [replan] cycle ${e.cycle}: ${e.subtaskIds?.join(", ")}`);
|
|
38689
39123
|
} else {
|
|
38690
39124
|
const usage = e.usageByTag ? " | usage: " + Object.entries(e.usageByTag).map(([tag, u]) => `${tag}=${u.totalTokens}t`).join(", ") : "";
|
|
38691
|
-
|
|
39125
|
+
getDefaultChannel().writeLine(` ${pc.dim(ts)} [verify] ${e.decision ?? e.status ?? "?"}${e.explanation ? ` — ${e.explanation}` : ""}${usage}`);
|
|
38692
39126
|
}
|
|
38693
39127
|
}
|
|
38694
39128
|
}
|
|
@@ -38702,15 +39136,15 @@ function buildSessionCommands(program2) {
|
|
|
38702
39136
|
completion += e.completionTokens ?? 0;
|
|
38703
39137
|
cached += e.cachedTokens ?? 0;
|
|
38704
39138
|
}
|
|
38705
|
-
|
|
38706
|
-
|
|
39139
|
+
getDefaultChannel().writeLine("");
|
|
39140
|
+
getDefaultChannel().writeLine(pc.cyan(t("cli.session_usage", {
|
|
38707
39141
|
prompt,
|
|
38708
39142
|
completion,
|
|
38709
39143
|
total: prompt + completion
|
|
38710
39144
|
})));
|
|
38711
39145
|
if (cached > 0 && prompt > 0) {
|
|
38712
39146
|
const hit = Math.round(cached / prompt * 100);
|
|
38713
|
-
|
|
39147
|
+
getDefaultChannel().writeLine(pc.dim(t("cli.session_cache", {
|
|
38714
39148
|
hit,
|
|
38715
39149
|
cached,
|
|
38716
39150
|
uncached: Math.max(0, prompt - cached)
|
|
@@ -38721,32 +39155,32 @@ function buildSessionCommands(program2) {
|
|
|
38721
39155
|
session2.command("delete").argument("<id>", "Session id").description(t("cli.delete_session")).action(async (id) => {
|
|
38722
39156
|
const { sessionManager } = await bootstrap();
|
|
38723
39157
|
sessionManager.delete(id);
|
|
38724
|
-
|
|
39158
|
+
getDefaultChannel().writeLine(t("session.deleted", { id }));
|
|
38725
39159
|
});
|
|
38726
39160
|
}
|
|
38727
39161
|
function buildChangelogCommand(program2) {
|
|
38728
39162
|
program2.command("changelog").description(t("cli.changelog_title", { version })).option("--from <version>", t("cli.changelog_range", { from: "..." })).action((opts) => {
|
|
38729
39163
|
const changelog = readChangelog("micro-models-agent");
|
|
38730
39164
|
if (!changelog) {
|
|
38731
|
-
|
|
39165
|
+
getDefaultChannel().writeLine(pc.yellow(t("cli.changelog_not_found")));
|
|
38732
39166
|
return;
|
|
38733
39167
|
}
|
|
38734
39168
|
if (opts.from) {
|
|
38735
39169
|
const range = extractChangelogRange(changelog, opts.from, version);
|
|
38736
39170
|
if (!range) {
|
|
38737
|
-
|
|
39171
|
+
getDefaultChannel().writeLine(pc.yellow(t("cli.changelog_not_found")));
|
|
38738
39172
|
return;
|
|
38739
39173
|
}
|
|
38740
|
-
|
|
38741
|
-
|
|
39174
|
+
getDefaultChannel().writeLine(pc.cyan(t("cli.changelog_range", { from: opts.from })));
|
|
39175
|
+
getDefaultChannel().writeLine(range);
|
|
38742
39176
|
} else {
|
|
38743
39177
|
const latest = extractLatestChangelog(changelog);
|
|
38744
39178
|
if (!latest) {
|
|
38745
|
-
|
|
39179
|
+
getDefaultChannel().writeLine(pc.yellow(t("cli.changelog_not_found")));
|
|
38746
39180
|
return;
|
|
38747
39181
|
}
|
|
38748
|
-
|
|
38749
|
-
|
|
39182
|
+
getDefaultChannel().writeLine(pc.cyan(t("cli.changelog_title", { version })));
|
|
39183
|
+
getDefaultChannel().writeLine(latest);
|
|
38750
39184
|
}
|
|
38751
39185
|
});
|
|
38752
39186
|
}
|
|
@@ -38781,11 +39215,11 @@ init_bootstrap();
|
|
|
38781
39215
|
|
|
38782
39216
|
// src/cli/repl.ts
|
|
38783
39217
|
init_colors();
|
|
38784
|
-
import * as
|
|
39218
|
+
import * as readline2 from "readline";
|
|
38785
39219
|
|
|
38786
39220
|
// src/ui/line-editor.ts
|
|
38787
39221
|
init_string_width();
|
|
38788
|
-
import * as
|
|
39222
|
+
import * as readline from "readline";
|
|
38789
39223
|
|
|
38790
39224
|
// src/ui/line-math.ts
|
|
38791
39225
|
init_string_width();
|
|
@@ -38907,6 +39341,10 @@ class LineEditor {
|
|
|
38907
39341
|
frameTopAbs = null;
|
|
38908
39342
|
dsrPending = false;
|
|
38909
39343
|
dsrTail = "";
|
|
39344
|
+
dsrQueryRow = 0;
|
|
39345
|
+
inputEnabled = true;
|
|
39346
|
+
frameSuspended = false;
|
|
39347
|
+
dsrTimer = null;
|
|
38910
39348
|
constructor(opts) {
|
|
38911
39349
|
this.input = opts.input;
|
|
38912
39350
|
this.output = opts.output;
|
|
@@ -38925,9 +39363,10 @@ class LineEditor {
|
|
|
38925
39363
|
this.enableTerminalProtocols();
|
|
38926
39364
|
this.dsrDataHandler = (buf) => this.consumeDsrReplies(buf.toString("utf-8"));
|
|
38927
39365
|
this.input.on("data", this.dsrDataHandler);
|
|
38928
|
-
|
|
39366
|
+
readline.emitKeypressEvents(this.input);
|
|
38929
39367
|
this.keypressHandler = (str, key) => this.onKey(str, key);
|
|
38930
39368
|
this.input.on("keypress", this.keypressHandler);
|
|
39369
|
+
this.input.resume?.();
|
|
38931
39370
|
} else {
|
|
38932
39371
|
this.dataHandler = (buf) => this.onData(buf);
|
|
38933
39372
|
this.input.on("data", this.dataHandler);
|
|
@@ -38964,6 +39403,61 @@ class LineEditor {
|
|
|
38964
39403
|
write(s) {
|
|
38965
39404
|
this.insertText(s);
|
|
38966
39405
|
}
|
|
39406
|
+
setInputEnabled(enabled2) {
|
|
39407
|
+
this.inputEnabled = enabled2;
|
|
39408
|
+
}
|
|
39409
|
+
isInputEnabled() {
|
|
39410
|
+
return this.inputEnabled;
|
|
39411
|
+
}
|
|
39412
|
+
isFrameSuspended() {
|
|
39413
|
+
return this.frameSuspended;
|
|
39414
|
+
}
|
|
39415
|
+
suspendFrame() {
|
|
39416
|
+
if (!this.input.isTTY || this.isDone)
|
|
39417
|
+
return;
|
|
39418
|
+
const out = [];
|
|
39419
|
+
if (this.frameTopAbs !== null)
|
|
39420
|
+
out.push(`\x1B[${this.frameTopAbs};1H`);
|
|
39421
|
+
else if (this.prevCursorRow > 0)
|
|
39422
|
+
out.push(`\x1B[${this.prevCursorRow}A`);
|
|
39423
|
+
out.push("\r\x1B[J");
|
|
39424
|
+
this.output.write(out.join(""));
|
|
39425
|
+
this.invalidateAnchor();
|
|
39426
|
+
this.frameSuspended = true;
|
|
39427
|
+
}
|
|
39428
|
+
resumeFrame() {
|
|
39429
|
+
this.frameSuspended = false;
|
|
39430
|
+
this.invalidateAnchor();
|
|
39431
|
+
this.render();
|
|
39432
|
+
}
|
|
39433
|
+
printAbove(text) {
|
|
39434
|
+
if (!this.input.isTTY || this.isDone) {
|
|
39435
|
+
this.output.write(text.endsWith(`
|
|
39436
|
+
`) ? text : `${text}
|
|
39437
|
+
`);
|
|
39438
|
+
return;
|
|
39439
|
+
}
|
|
39440
|
+
const wasSuspended = this.frameSuspended;
|
|
39441
|
+
this.frameSuspended = false;
|
|
39442
|
+
const out = [];
|
|
39443
|
+
if (this.frameTopAbs !== null)
|
|
39444
|
+
out.push(`\x1B[${this.frameTopAbs};1H`);
|
|
39445
|
+
else if (this.prevCursorRow > 0)
|
|
39446
|
+
out.push(`\x1B[${this.prevCursorRow}A`);
|
|
39447
|
+
out.push("\r\x1B[J");
|
|
39448
|
+
out.push(text.replace(/\r\n/g, `
|
|
39449
|
+
`).replace(/\n$/, "").split(`
|
|
39450
|
+
`).join(`\r
|
|
39451
|
+
`));
|
|
39452
|
+
out.push(`\r
|
|
39453
|
+
`);
|
|
39454
|
+
this.output.write(out.join(""));
|
|
39455
|
+
this.invalidateAnchor();
|
|
39456
|
+
if (wasSuspended)
|
|
39457
|
+
this.frameSuspended = true;
|
|
39458
|
+
else
|
|
39459
|
+
this.render();
|
|
39460
|
+
}
|
|
38967
39461
|
reset() {
|
|
38968
39462
|
this.lines = [""];
|
|
38969
39463
|
this.row = 0;
|
|
@@ -39001,6 +39495,10 @@ class LineEditor {
|
|
|
39001
39495
|
if (this.rawMode && this.input.setRawMode) {
|
|
39002
39496
|
this.input.setRawMode(false);
|
|
39003
39497
|
}
|
|
39498
|
+
if (this.dsrTimer) {
|
|
39499
|
+
clearTimeout(this.dsrTimer);
|
|
39500
|
+
this.dsrTimer = null;
|
|
39501
|
+
}
|
|
39004
39502
|
this.emitClose();
|
|
39005
39503
|
}
|
|
39006
39504
|
onData(buf) {
|
|
@@ -39029,6 +39527,18 @@ class LineEditor {
|
|
|
39029
39527
|
onKey(str, key) {
|
|
39030
39528
|
if (this.isDone)
|
|
39031
39529
|
return;
|
|
39530
|
+
if (!this.inputEnabled) {
|
|
39531
|
+
const k2 = key;
|
|
39532
|
+
if (k2?.ctrl && k2.name === "c") {
|
|
39533
|
+
this.ctrlC();
|
|
39534
|
+
return;
|
|
39535
|
+
}
|
|
39536
|
+
if (k2?.name === "escape") {
|
|
39537
|
+
this.onKeyInput?.(str, key);
|
|
39538
|
+
return;
|
|
39539
|
+
}
|
|
39540
|
+
return;
|
|
39541
|
+
}
|
|
39032
39542
|
if (this.onKeyInput && this.onKeyInput(str, key))
|
|
39033
39543
|
return;
|
|
39034
39544
|
const k = key;
|
|
@@ -39041,6 +39551,8 @@ class LineEditor {
|
|
|
39041
39551
|
}
|
|
39042
39552
|
return;
|
|
39043
39553
|
}
|
|
39554
|
+
if (/^\x1b\[\d+;\d+R$/.test(seq2))
|
|
39555
|
+
return;
|
|
39044
39556
|
if (name === "paste-start" || seq2 === "\x1B[200~") {
|
|
39045
39557
|
this.isPaste = true;
|
|
39046
39558
|
this.pasteBuffer = "";
|
|
@@ -39557,6 +40069,13 @@ class LineEditor {
|
|
|
39557
40069
|
const r = this.output.rows;
|
|
39558
40070
|
return typeof r === "number" && r > 3 ? r : null;
|
|
39559
40071
|
}
|
|
40072
|
+
dsrEnabled() {
|
|
40073
|
+
if (process.env.MMA_DSR === "1")
|
|
40074
|
+
return true;
|
|
40075
|
+
if (process.env.MMA_DSR === "0")
|
|
40076
|
+
return false;
|
|
40077
|
+
return process.platform !== "win32";
|
|
40078
|
+
}
|
|
39560
40079
|
visibleLayout() {
|
|
39561
40080
|
const layout = this.layout();
|
|
39562
40081
|
const H = this.screenRows();
|
|
@@ -39571,6 +40090,10 @@ class LineEditor {
|
|
|
39571
40090
|
this.dsrPending = false;
|
|
39572
40091
|
this.dsrTail = "";
|
|
39573
40092
|
this.prevCursorRow = 0;
|
|
40093
|
+
if (this.dsrTimer) {
|
|
40094
|
+
clearTimeout(this.dsrTimer);
|
|
40095
|
+
this.dsrTimer = null;
|
|
40096
|
+
}
|
|
39574
40097
|
}
|
|
39575
40098
|
consumeDsrReplies(chunk) {
|
|
39576
40099
|
this.dsrTail = (this.dsrTail + chunk).slice(-80);
|
|
@@ -39582,13 +40105,17 @@ class LineEditor {
|
|
|
39582
40105
|
return;
|
|
39583
40106
|
this.dsrPending = false;
|
|
39584
40107
|
const row = Number(m[1]);
|
|
39585
|
-
|
|
39586
|
-
|
|
39587
|
-
|
|
40108
|
+
if (this.dsrTimer) {
|
|
40109
|
+
clearTimeout(this.dsrTimer);
|
|
40110
|
+
this.dsrTimer = null;
|
|
40111
|
+
}
|
|
40112
|
+
const top = row - this.dsrQueryRow;
|
|
40113
|
+
const H = this.screenRows();
|
|
40114
|
+
if (top >= 1 && (H === null || top <= H))
|
|
39588
40115
|
this.frameTopAbs = top;
|
|
39589
40116
|
}
|
|
39590
40117
|
render() {
|
|
39591
|
-
if (!this.input.isTTY || this.isDone)
|
|
40118
|
+
if (!this.input.isTTY || this.isDone || this.frameSuspended)
|
|
39592
40119
|
return;
|
|
39593
40120
|
const layout = this.visibleLayout();
|
|
39594
40121
|
const promptWidth = stringWidth(stripAnsi2(this.promptStr));
|
|
@@ -39621,6 +40148,7 @@ class LineEditor {
|
|
|
39621
40148
|
if (ccol > 0)
|
|
39622
40149
|
out.push(`\x1B[${ccol}C`);
|
|
39623
40150
|
this.output.write(out.join(""));
|
|
40151
|
+
this.prevCursorRow = idx;
|
|
39624
40152
|
if (this.frameTopAbs !== null) {
|
|
39625
40153
|
const H = this.screenRows();
|
|
39626
40154
|
if (H) {
|
|
@@ -39629,8 +40157,17 @@ class LineEditor {
|
|
|
39629
40157
|
if (T + L - 1 > H)
|
|
39630
40158
|
this.frameTopAbs = H - L + 1;
|
|
39631
40159
|
}
|
|
39632
|
-
} else if (!this.dsrPending) {
|
|
39633
|
-
|
|
40160
|
+
} else if (!this.dsrPending && this.questionCb === null && this.dsrEnabled()) {
|
|
40161
|
+
this.dsrPending = true;
|
|
40162
|
+
this.dsrQueryRow = idx;
|
|
40163
|
+
this.output.write("\x1B[6n");
|
|
40164
|
+
if (this.dsrTimer)
|
|
40165
|
+
clearTimeout(this.dsrTimer);
|
|
40166
|
+
this.dsrTimer = setTimeout(() => {
|
|
40167
|
+
this.dsrPending = false;
|
|
40168
|
+
this.dsrTimer = null;
|
|
40169
|
+
}, 150);
|
|
40170
|
+
}
|
|
39634
40171
|
}
|
|
39635
40172
|
enableTerminalProtocols() {
|
|
39636
40173
|
this.output.write("\x1B[?2004h");
|
|
@@ -39649,8 +40186,8 @@ class LineEditor {
|
|
|
39649
40186
|
}
|
|
39650
40187
|
|
|
39651
40188
|
// src/cli/repl.ts
|
|
39652
|
-
import { existsSync as existsSync60, readFileSync as readFileSync41, writeFileSync as writeFileSync24 } from "fs";
|
|
39653
|
-
import { join as join55 } from "path";
|
|
40189
|
+
import { existsSync as existsSync60, mkdirSync as mkdirSync23, readFileSync as readFileSync41, writeFileSync as writeFileSync24 } from "fs";
|
|
40190
|
+
import { dirname as dirname25, join as join55 } from "path";
|
|
39654
40191
|
import { homedir as homedir18 } from "os";
|
|
39655
40192
|
|
|
39656
40193
|
// src/cli/completer.ts
|
|
@@ -39783,6 +40320,7 @@ init_colors();
|
|
|
39783
40320
|
|
|
39784
40321
|
// src/ui/md-formatter.ts
|
|
39785
40322
|
init_colors();
|
|
40323
|
+
init_string_width();
|
|
39786
40324
|
init_i18n();
|
|
39787
40325
|
init_table();
|
|
39788
40326
|
var KW = /\b(import|export|from|const|let|var|function|return|if|else|for|while|do|switch|case|break|continue|new|class|extends|implements|interface|type|enum|namespace|module|declare|abstract|async|await|yield|throw|try|catch|finally|typeof|instanceof|in|of|as|is|keyof|readonly|static|private|public|protected|get|set|constructor|this|super|void|never|any|unknown|boolean|string|number|symbol|object|true|false|null|undefined|default)\b/g;
|
|
@@ -39793,24 +40331,24 @@ var TAG = /<\/?([A-Z][a-zA-Z0-9]*|[a-z][a-zA-Z0-9-]*)/g;
|
|
|
39793
40331
|
var ATTR = /\b([a-zA-Z-]+=)"([^"]*)"/g;
|
|
39794
40332
|
function highlight(code, lang) {
|
|
39795
40333
|
if (lang === "html" || lang === "xml" || lang === "svg") {
|
|
39796
|
-
code = code.replace(COMMENT, (m) =>
|
|
39797
|
-
code = code.replace(ATTR, (_m, attr, val) =>
|
|
39798
|
-
code = code.replace(TAG, (_m, tag) => "<" +
|
|
40334
|
+
code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
|
|
40335
|
+
code = code.replace(ATTR, (_m, attr, val) => pc.yellow(attr) + "=" + pc.green('"' + val + '"'));
|
|
40336
|
+
code = code.replace(TAG, (_m, tag) => "<" + pc.cyan(tag));
|
|
39799
40337
|
} else if (lang === "css" || lang === "scss" || lang === "less") {
|
|
39800
|
-
code = code.replace(COMMENT, (m) =>
|
|
39801
|
-
code = code.replace(STRING, (m) =>
|
|
39802
|
-
code = code.replace(NUMBER, (m) =>
|
|
40338
|
+
code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
|
|
40339
|
+
code = code.replace(STRING, (m) => pc.green(m));
|
|
40340
|
+
code = code.replace(NUMBER, (m) => pc.yellow(m));
|
|
39803
40341
|
} else if (lang === "bash" || lang === "sh" || lang === "shell" || lang === "zsh") {
|
|
39804
|
-
code = code.replace(COMMENT, (m) =>
|
|
39805
|
-
code = code.replace(STRING, (m) =>
|
|
40342
|
+
code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
|
|
40343
|
+
code = code.replace(STRING, (m) => pc.green(m));
|
|
39806
40344
|
} else if (lang === "json") {
|
|
39807
|
-
code = code.replace(STRING, (m) =>
|
|
39808
|
-
code = code.replace(NUMBER, (m) =>
|
|
40345
|
+
code = code.replace(STRING, (m) => pc.green(m));
|
|
40346
|
+
code = code.replace(NUMBER, (m) => pc.yellow(m));
|
|
39809
40347
|
} else {
|
|
39810
|
-
code = code.replace(COMMENT, (m) =>
|
|
39811
|
-
code = code.replace(STRING, (m) =>
|
|
39812
|
-
code = code.replace(KW, (m) =>
|
|
39813
|
-
code = code.replace(NUMBER, (m) =>
|
|
40348
|
+
code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
|
|
40349
|
+
code = code.replace(STRING, (m) => pc.green(m));
|
|
40350
|
+
code = code.replace(KW, (m) => pc.magenta(m));
|
|
40351
|
+
code = code.replace(NUMBER, (m) => pc.yellow(m));
|
|
39814
40352
|
}
|
|
39815
40353
|
return code;
|
|
39816
40354
|
}
|
|
@@ -39835,10 +40373,15 @@ class FormattingStream {
|
|
|
39835
40373
|
onRawWrite;
|
|
39836
40374
|
width;
|
|
39837
40375
|
partialWritten = 0;
|
|
39838
|
-
|
|
40376
|
+
streamedChars = 0;
|
|
40377
|
+
reservedCols;
|
|
40378
|
+
streamPartials;
|
|
40379
|
+
constructor(onWrite, width, onRawWrite, opts = {}) {
|
|
39839
40380
|
this.onWrite = onWrite;
|
|
39840
40381
|
this.onRawWrite = onRawWrite ?? onWrite;
|
|
39841
40382
|
this.width = width ?? getTerminalWidth();
|
|
40383
|
+
this.reservedCols = opts.reservedCols ?? 0;
|
|
40384
|
+
this.streamPartials = opts.streamPartials ?? false;
|
|
39842
40385
|
}
|
|
39843
40386
|
write(chunk) {
|
|
39844
40387
|
this.buffer += chunk;
|
|
@@ -39851,15 +40394,47 @@ class FormattingStream {
|
|
|
39851
40394
|
this.processLine(line);
|
|
39852
40395
|
}
|
|
39853
40396
|
if (this.buffer.length > 0 && !this.inCodeBlock) {
|
|
39854
|
-
this.
|
|
39855
|
-
this.partialWritten = this.buffer.length;
|
|
39856
|
-
this.buffer = "";
|
|
40397
|
+
this.streamPartial();
|
|
39857
40398
|
}
|
|
39858
40399
|
}
|
|
40400
|
+
streamPartial() {
|
|
40401
|
+
if (!this.streamPartials)
|
|
40402
|
+
return;
|
|
40403
|
+
const available = Math.max(1, this.width - this.reservedCols);
|
|
40404
|
+
if (stringWidth(this.buffer) > available)
|
|
40405
|
+
return;
|
|
40406
|
+
const delta = this.buffer.slice(this.streamedChars);
|
|
40407
|
+
if (!delta)
|
|
40408
|
+
return;
|
|
40409
|
+
this.onRawWrite(delta);
|
|
40410
|
+
this.streamedChars = this.buffer.length;
|
|
40411
|
+
this.partialWritten = stringWidth(this.buffer);
|
|
40412
|
+
}
|
|
39859
40413
|
emitPartialRewind() {
|
|
39860
40414
|
if (this.partialWritten > 0) {
|
|
39861
|
-
this.onRawWrite(`\x1B[${this.partialWritten}D`);
|
|
40415
|
+
this.onRawWrite(`\x1B[${this.partialWritten}D\x1B[K`);
|
|
40416
|
+
this.partialWritten = 0;
|
|
40417
|
+
}
|
|
40418
|
+
this.streamedChars = 0;
|
|
40419
|
+
}
|
|
40420
|
+
hasPartial() {
|
|
40421
|
+
return this.partialWritten > 0 || this.buffer.length > 0 || this.tableBuffer.length > 0;
|
|
40422
|
+
}
|
|
40423
|
+
flushPartialNow() {
|
|
40424
|
+
if (this.partialWritten > 0) {
|
|
40425
|
+
this.onRawWrite(`
|
|
40426
|
+
`);
|
|
39862
40427
|
this.partialWritten = 0;
|
|
40428
|
+
this.streamedChars = 0;
|
|
40429
|
+
this.buffer = "";
|
|
40430
|
+
} else if (this.buffer.length > 0 && !this.inCodeBlock) {
|
|
40431
|
+
const line = this.buffer;
|
|
40432
|
+
this.buffer = "";
|
|
40433
|
+
this.streamedChars = 0;
|
|
40434
|
+
this.onWrite(this.formatLine(line));
|
|
40435
|
+
}
|
|
40436
|
+
if (this.tableBuffer.length > 0) {
|
|
40437
|
+
this.flushTable();
|
|
39863
40438
|
}
|
|
39864
40439
|
}
|
|
39865
40440
|
flush() {
|
|
@@ -39874,13 +40449,16 @@ class FormattingStream {
|
|
|
39874
40449
|
if (this.codeLines.length > 0) {
|
|
39875
40450
|
this.emitCodeBlock();
|
|
39876
40451
|
}
|
|
40452
|
+
this.streamedChars = 0;
|
|
39877
40453
|
return;
|
|
39878
40454
|
}
|
|
39879
40455
|
if (this.buffer.length > 0) {
|
|
39880
40456
|
const line = this.buffer;
|
|
39881
40457
|
this.buffer = "";
|
|
40458
|
+
this.emitPartialRewind();
|
|
39882
40459
|
this.onWrite(this.formatLine(line));
|
|
39883
40460
|
}
|
|
40461
|
+
this.streamedChars = 0;
|
|
39884
40462
|
}
|
|
39885
40463
|
processLine(line) {
|
|
39886
40464
|
if (line.trim() === "```" || line.trim().startsWith("```")) {
|
|
@@ -39927,13 +40505,13 @@ class FormattingStream {
|
|
|
39927
40505
|
`);
|
|
39928
40506
|
const highlighted = highlight(code, this.codeLang);
|
|
39929
40507
|
const lang = this.codeLang ? ` ${this.codeLang} ` : " ";
|
|
39930
|
-
const top =
|
|
40508
|
+
const top = pc.dim(`┌─${lang}${"─".repeat(Math.max(0, this.width - 3 - lang.length))}┐`);
|
|
39931
40509
|
this.onWrite(top);
|
|
39932
40510
|
for (const l of highlighted.split(`
|
|
39933
40511
|
`)) {
|
|
39934
|
-
this.onWrite(
|
|
40512
|
+
this.onWrite(pc.dim("│ ") + l);
|
|
39935
40513
|
}
|
|
39936
|
-
this.onWrite(
|
|
40514
|
+
this.onWrite(pc.dim(`└${"─".repeat(Math.max(0, this.width - 1))}┘`));
|
|
39937
40515
|
}
|
|
39938
40516
|
this.codeLines = [];
|
|
39939
40517
|
this.codeLang = "";
|
|
@@ -39945,54 +40523,54 @@ class FormattingStream {
|
|
|
39945
40523
|
const level = heading[1].length;
|
|
39946
40524
|
const content = this.formatInline(heading[2]);
|
|
39947
40525
|
if (level === 1)
|
|
39948
|
-
return
|
|
39949
|
-
return
|
|
40526
|
+
return pc.cyan(pc.bold(pc.underline(content)));
|
|
40527
|
+
return pc.cyan(pc.bold(content));
|
|
39950
40528
|
}
|
|
39951
40529
|
if (isHorizontalRule(result)) {
|
|
39952
|
-
return
|
|
40530
|
+
return pc.dim("─".repeat(Math.max(0, Math.min(this.width, 60))));
|
|
39953
40531
|
}
|
|
39954
40532
|
const quote = result.match(/^(>+)\s?(.*)$/);
|
|
39955
40533
|
if (quote) {
|
|
39956
40534
|
const depth = Math.min(quote[1].length, 4);
|
|
39957
|
-
const marker =
|
|
40535
|
+
const marker = pc.dim("▍".repeat(depth));
|
|
39958
40536
|
return `${marker} ${this.formatInline(quote[2])}`;
|
|
39959
40537
|
}
|
|
39960
40538
|
const checkbox = result.match(/^[-*]\s+\[([ xX])\]\s+(.+)$/);
|
|
39961
40539
|
if (checkbox) {
|
|
39962
40540
|
const checked = checkbox[1].toLowerCase() === "x";
|
|
39963
|
-
const mark = checked ?
|
|
40541
|
+
const mark = checked ? pc.green("✓") : pc.dim("☐");
|
|
39964
40542
|
return ` ${mark} ${this.formatInline(checkbox[2])}`;
|
|
39965
40543
|
}
|
|
39966
40544
|
const ordered = result.match(/^(\d+)[.)]\s+(.+)$/);
|
|
39967
40545
|
if (ordered) {
|
|
39968
|
-
return ` ${
|
|
40546
|
+
return ` ${pc.yellow(ordered[1])}. ${this.formatInline(ordered[2])}`;
|
|
39969
40547
|
}
|
|
39970
40548
|
const bullet = result.match(/^[-*]\s+(.+)$/);
|
|
39971
40549
|
if (bullet) {
|
|
39972
|
-
return ` ${
|
|
40550
|
+
return ` ${pc.dim("•")} ${this.formatInline(bullet[1])}`;
|
|
39973
40551
|
}
|
|
39974
40552
|
return this.formatInline(result);
|
|
39975
40553
|
}
|
|
39976
40554
|
formatInline(text) {
|
|
39977
40555
|
const codeSpans = [];
|
|
39978
40556
|
let result = text.replace(/`([^`]+)`/g, (_m, c) => {
|
|
39979
|
-
codeSpans.push(
|
|
40557
|
+
codeSpans.push(pc.yellow(c));
|
|
39980
40558
|
return `\x00${codeSpans.length - 1}\x00`;
|
|
39981
40559
|
});
|
|
39982
|
-
result = result.replace(/\*\*(.+?)\*\*/g, (_, s) =>
|
|
39983
|
-
result = result.replace(/~~(.+?)~~/g, (_, s) =>
|
|
39984
|
-
result = result.replace(/\*([^*]+)\*/g, (_, s) =>
|
|
39985
|
-
result = result.replace(/(^|\s)_([^_\n]+)_(?=\s|$)/g, (_m, pre, s) => pre +
|
|
40560
|
+
result = result.replace(/\*\*(.+?)\*\*/g, (_, s) => pc.bold(s));
|
|
40561
|
+
result = result.replace(/~~(.+?)~~/g, (_, s) => pc.strikethrough(s));
|
|
40562
|
+
result = result.replace(/\*([^*]+)\*/g, (_, s) => pc.italic(s));
|
|
40563
|
+
result = result.replace(/(^|\s)_([^_\n]+)_(?=\s|$)/g, (_m, pre, s) => pre + pc.italic(s));
|
|
39986
40564
|
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => {
|
|
39987
40565
|
const short = url.length > 80 ? url.slice(0, 77) + "…" : url;
|
|
39988
|
-
return `${
|
|
40566
|
+
return `${pc.cyan(label)} ${pc.dim(`(${short})`)}`;
|
|
39989
40567
|
});
|
|
39990
40568
|
result = result.replace(/\u0000(\d+)\u0000/g, (_m, i) => codeSpans[Number(i)]);
|
|
39991
40569
|
return result;
|
|
39992
40570
|
}
|
|
39993
40571
|
}
|
|
39994
40572
|
function formatWarning(text) {
|
|
39995
|
-
return
|
|
40573
|
+
return pc.yellow(pc.bold(t("ui.warning_prefix")) + text);
|
|
39996
40574
|
}
|
|
39997
40575
|
|
|
39998
40576
|
// src/ui/renderer.ts
|
|
@@ -40000,6 +40578,7 @@ init_spinner();
|
|
|
40000
40578
|
init_table();
|
|
40001
40579
|
init_i18n();
|
|
40002
40580
|
init_prices();
|
|
40581
|
+
init_output();
|
|
40003
40582
|
import { isAbsolute as isAbsolute5, relative as relative8, sep as sep2 } from "path";
|
|
40004
40583
|
function formatUsd(cost) {
|
|
40005
40584
|
return formatCost(cost);
|
|
@@ -40072,8 +40651,7 @@ class Renderer {
|
|
|
40072
40651
|
rich;
|
|
40073
40652
|
spinner;
|
|
40074
40653
|
fmt;
|
|
40075
|
-
|
|
40076
|
-
err;
|
|
40654
|
+
channel;
|
|
40077
40655
|
width;
|
|
40078
40656
|
baseDir;
|
|
40079
40657
|
card = null;
|
|
@@ -40085,17 +40663,16 @@ class Renderer {
|
|
|
40085
40663
|
outputSuppressed = false;
|
|
40086
40664
|
constructor(opts = {}) {
|
|
40087
40665
|
this.rich = opts.rich ?? isRichTerminal();
|
|
40088
|
-
this.out = opts.out ?? process.stdout;
|
|
40089
|
-
this.err = opts.err ?? process.stderr;
|
|
40090
40666
|
this.width = opts.width ?? getTerminalWidth();
|
|
40091
40667
|
this.baseDir = opts.baseDir;
|
|
40668
|
+
this.channel = opts.channel ?? getDefaultChannel();
|
|
40092
40669
|
this.spinner = new Spinner({
|
|
40093
40670
|
enabled: this.rich && (opts.spinner ?? true),
|
|
40094
|
-
|
|
40671
|
+
channel: this.channel,
|
|
40095
40672
|
width: this.width
|
|
40096
40673
|
});
|
|
40097
|
-
this.fmt = new FormattingStream((line) => this.
|
|
40098
|
-
`), this.width, (text) => this.
|
|
40674
|
+
this.fmt = new FormattingStream((line) => this.channel.writeRaw(`${line}
|
|
40675
|
+
`), this.width, (text) => this.channel.writeRaw(text), { reservedCols: 2, streamPartials: this.rich });
|
|
40099
40676
|
}
|
|
40100
40677
|
showLoader() {
|
|
40101
40678
|
this.spinner.start(t("ui.thinking"));
|
|
@@ -40105,8 +40682,8 @@ class Renderer {
|
|
|
40105
40682
|
this.spinner.stop();
|
|
40106
40683
|
if (!this.textStarted) {
|
|
40107
40684
|
this.textStarted = true;
|
|
40108
|
-
this.
|
|
40109
|
-
${
|
|
40685
|
+
this.channel.writeRaw(`
|
|
40686
|
+
${pc.dim("-")} `);
|
|
40110
40687
|
}
|
|
40111
40688
|
this.fmt.write(chunk);
|
|
40112
40689
|
}
|
|
@@ -40114,15 +40691,15 @@ ${pc2.dim("-")} `);
|
|
|
40114
40691
|
this.spinner.stop();
|
|
40115
40692
|
if (this.thoughtStarted) {
|
|
40116
40693
|
if (!this.thoughtHeaderPrinted) {
|
|
40117
|
-
this.
|
|
40118
|
-
${
|
|
40694
|
+
this.channel.writeRaw(`
|
|
40695
|
+
${pc.dim("→")} Thought: `);
|
|
40119
40696
|
this.thoughtHeaderPrinted = true;
|
|
40120
40697
|
}
|
|
40121
|
-
this.
|
|
40698
|
+
this.channel.writeRaw(pc.dim(chunk));
|
|
40122
40699
|
} else if (this.card) {
|
|
40123
40700
|
this.writeInlineBody(chunk);
|
|
40124
40701
|
} else {
|
|
40125
|
-
this.
|
|
40702
|
+
this.channel.writeRaw(chunk);
|
|
40126
40703
|
}
|
|
40127
40704
|
}
|
|
40128
40705
|
writeInlineBody(chunk) {
|
|
@@ -40135,18 +40712,18 @@ ${pc2.dim("→")} Thought: `);
|
|
|
40135
40712
|
this.outputSuppressed = true;
|
|
40136
40713
|
continue;
|
|
40137
40714
|
}
|
|
40138
|
-
this.
|
|
40715
|
+
this.channel.writeRaw(`${GUTTER}${line}
|
|
40139
40716
|
`);
|
|
40140
40717
|
}
|
|
40141
40718
|
}
|
|
40142
40719
|
reasoning(chunk) {
|
|
40143
40720
|
this.spinner.stop();
|
|
40144
40721
|
if (this.thoughtStarted && !this.thoughtHeaderPrinted) {
|
|
40145
|
-
this.
|
|
40146
|
-
${
|
|
40722
|
+
this.channel.writeRaw(`
|
|
40723
|
+
${pc.dim("→")} Thought: `);
|
|
40147
40724
|
this.thoughtHeaderPrinted = true;
|
|
40148
40725
|
}
|
|
40149
|
-
this.
|
|
40726
|
+
this.channel.writeRaw(pc.dim(chunk));
|
|
40150
40727
|
}
|
|
40151
40728
|
thinkingStart() {
|
|
40152
40729
|
this.thoughtStarted = true;
|
|
@@ -40158,15 +40735,16 @@ ${pc2.dim("→")} Thought: `);
|
|
|
40158
40735
|
this.spinner.stop();
|
|
40159
40736
|
if (this.thoughtStarted && this.thoughtHeaderPrinted) {
|
|
40160
40737
|
const duration = Date.now() - this.thoughtStartMs;
|
|
40161
|
-
this.
|
|
40738
|
+
this.channel.writeRaw(pc.dim(` ${duration}ms
|
|
40162
40739
|
`));
|
|
40163
40740
|
}
|
|
40164
40741
|
this.thoughtStarted = false;
|
|
40165
40742
|
this.thoughtHeaderPrinted = false;
|
|
40166
40743
|
}
|
|
40167
40744
|
toolStart(tool, args, stepContext, icon) {
|
|
40168
|
-
this.endCard();
|
|
40169
40745
|
this.spinner.stop();
|
|
40746
|
+
this.fmt.flushPartialNow();
|
|
40747
|
+
this.endCard();
|
|
40170
40748
|
this.outputLineCount = 0;
|
|
40171
40749
|
this.outputSuppressed = false;
|
|
40172
40750
|
const displayArgs = PATH_TOOLS.has(tool) && typeof args.path === "string" ? { ...args, path: toDisplayPath(this.baseDir, args.path) } : args;
|
|
@@ -40175,65 +40753,70 @@ ${pc2.dim("→")} Thought: `);
|
|
|
40175
40753
|
const label = friendlyTool(tool);
|
|
40176
40754
|
this.card = { tool, args, start: Date.now() };
|
|
40177
40755
|
if (stepContext) {
|
|
40178
|
-
this.
|
|
40179
|
-
${
|
|
40756
|
+
this.channel.writeRaw(`
|
|
40757
|
+
${pc.dim("↓")} ${pc.cyan(stepContext)}
|
|
40180
40758
|
`);
|
|
40181
40759
|
}
|
|
40182
|
-
this.
|
|
40760
|
+
this.channel.writeRaw(`${pc.dim(marker)} ${label}${summary ? ` ${pc.dim(summary)}` : ""}
|
|
40183
40761
|
`);
|
|
40184
40762
|
if (!SPINNERLESS_TOOLS.has(tool)) {
|
|
40185
40763
|
this.spinner.start(`${label}${summary ? ` ${summary}` : ""}`);
|
|
40186
40764
|
}
|
|
40187
40765
|
}
|
|
40188
40766
|
planBlock(lines) {
|
|
40189
|
-
this.endCard();
|
|
40190
40767
|
this.spinner.stop();
|
|
40768
|
+
this.fmt.flushPartialNow();
|
|
40769
|
+
this.endCard();
|
|
40191
40770
|
for (const line of lines) {
|
|
40192
|
-
this.
|
|
40771
|
+
this.channel.writeRaw(`${line}
|
|
40193
40772
|
`);
|
|
40194
40773
|
}
|
|
40195
40774
|
}
|
|
40196
40775
|
toolEnd(_tool, duration, error, ctxDelta, costUsd) {
|
|
40197
40776
|
this.spinner.stop();
|
|
40777
|
+
this.fmt.flushPartialNow();
|
|
40198
40778
|
if (!this.card)
|
|
40199
40779
|
return;
|
|
40200
|
-
const marker = error ?
|
|
40201
|
-
let footer = `${GUTTER}${marker} ${
|
|
40780
|
+
const marker = error ? pc.red("✗") : pc.green("✓");
|
|
40781
|
+
let footer = `${GUTTER}${marker} ${pc.dim(`${duration}ms`)}`;
|
|
40202
40782
|
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
40203
|
-
const deltaStr = ctxDelta > 0 ?
|
|
40204
|
-
footer += ` ${
|
|
40783
|
+
const deltaStr = ctxDelta > 0 ? pc.green(`+${ctxDelta}`) : pc.yellow(`${ctxDelta} ↓`);
|
|
40784
|
+
footer += ` ${pc.dim("ctx")} ${deltaStr}`;
|
|
40205
40785
|
}
|
|
40206
40786
|
if (costUsd !== undefined && costUsd > 0) {
|
|
40207
|
-
footer += ` ${
|
|
40787
|
+
footer += ` ${pc.dim("cost")} ${pc.yellow(formatUsd(costUsd))}`;
|
|
40208
40788
|
}
|
|
40209
|
-
this.
|
|
40789
|
+
this.channel.writeRaw(`${footer}
|
|
40210
40790
|
`);
|
|
40211
40791
|
if (this.outputSuppressed) {
|
|
40212
|
-
this.
|
|
40792
|
+
this.channel.writeRaw(`${GUTTER}${pc.dim(`... (${this.outputLineCount - MAX_OUTPUT_LINES} more lines)`)}
|
|
40213
40793
|
`);
|
|
40214
40794
|
}
|
|
40215
40795
|
this.card = null;
|
|
40216
40796
|
}
|
|
40217
40797
|
raw(text) {
|
|
40218
|
-
this.endCard();
|
|
40219
40798
|
this.spinner.stop();
|
|
40220
|
-
this.
|
|
40799
|
+
this.fmt.flushPartialNow();
|
|
40800
|
+
this.endCard();
|
|
40801
|
+
this.channel.writeRaw(text);
|
|
40221
40802
|
}
|
|
40222
40803
|
error(text) {
|
|
40223
|
-
this.endCard();
|
|
40224
40804
|
this.spinner.stop();
|
|
40225
|
-
this.
|
|
40226
|
-
|
|
40805
|
+
this.fmt.flushPartialNow();
|
|
40806
|
+
this.endCard();
|
|
40807
|
+
this.channel.writeRaw(`${pc.red(text)}
|
|
40808
|
+
`, "stderr");
|
|
40227
40809
|
}
|
|
40228
40810
|
flush() {
|
|
40229
40811
|
this.endCard();
|
|
40230
40812
|
this.spinner.stop();
|
|
40813
|
+
this.fmt.flushPartialNow();
|
|
40231
40814
|
this.fmt.flush();
|
|
40232
40815
|
this.textStarted = false;
|
|
40233
40816
|
}
|
|
40234
40817
|
footer(model, provider, durationMs) {
|
|
40235
|
-
this.
|
|
40236
|
-
${
|
|
40818
|
+
this.channel.writeRaw(`
|
|
40819
|
+
${pc.dim("▣")} ${model} · ${provider} · ${pc.dim(`${durationMs}ms`)}
|
|
40237
40820
|
`);
|
|
40238
40821
|
}
|
|
40239
40822
|
endCard() {
|
|
@@ -40339,15 +40922,15 @@ function currentStepIndex(plan) {
|
|
|
40339
40922
|
function stepMark(step) {
|
|
40340
40923
|
switch (step.status) {
|
|
40341
40924
|
case "done":
|
|
40342
|
-
return
|
|
40925
|
+
return pc.green("[x]");
|
|
40343
40926
|
case "in_progress":
|
|
40344
|
-
return
|
|
40927
|
+
return pc.yellow("[*]");
|
|
40345
40928
|
case "failed":
|
|
40346
|
-
return
|
|
40929
|
+
return pc.red("[!]");
|
|
40347
40930
|
case "skipped":
|
|
40348
|
-
return
|
|
40931
|
+
return pc.dim("[-]");
|
|
40349
40932
|
default:
|
|
40350
|
-
return
|
|
40933
|
+
return pc.dim("[ ]");
|
|
40351
40934
|
}
|
|
40352
40935
|
}
|
|
40353
40936
|
function formatPlanChecklist(plan) {
|
|
@@ -40357,18 +40940,18 @@ function formatPlanChecklist(plan) {
|
|
|
40357
40940
|
const cur = currentStepIndex(plan);
|
|
40358
40941
|
const barLen = 15;
|
|
40359
40942
|
const filled = Math.round(pct / 100 * barLen);
|
|
40360
|
-
const bar =
|
|
40943
|
+
const bar = pc.green("█".repeat(filled)) + pc.dim("░".repeat(barLen - filled));
|
|
40361
40944
|
const title = plan.title.replace(/^\[\d+[^]]*\]\s*/, "");
|
|
40362
40945
|
const lines = [
|
|
40363
|
-
`${
|
|
40946
|
+
`${pc.cyan(`[${plan.id}]`)} ${pc.bold(title)} ${bar} ${pc.dim(`${done}/${total} ${pct}%`)}`
|
|
40364
40947
|
];
|
|
40365
40948
|
for (let i = 0;i < plan.steps.length; i++) {
|
|
40366
40949
|
const step = plan.steps[i];
|
|
40367
40950
|
const active = i === cur;
|
|
40368
|
-
const desc = active ?
|
|
40951
|
+
const desc = active ? pc.yellow(step.description) : pc.dim(step.description);
|
|
40369
40952
|
lines.push(` ${stepMark(step)} ${step.id}. ${desc}`);
|
|
40370
40953
|
for (const sub of step.subtasks ?? []) {
|
|
40371
|
-
lines.push(` ${sub.done ?
|
|
40954
|
+
lines.push(` ${sub.done ? pc.green("[x]") : pc.dim("[ ]")} ${sub.text}`);
|
|
40372
40955
|
}
|
|
40373
40956
|
}
|
|
40374
40957
|
return lines;
|
|
@@ -40427,25 +41010,87 @@ function formatCacheLine(cache) {
|
|
|
40427
41010
|
return;
|
|
40428
41011
|
}
|
|
40429
41012
|
|
|
40430
|
-
// src/
|
|
40431
|
-
|
|
40432
|
-
|
|
41013
|
+
// src/cli/repl.ts
|
|
41014
|
+
init_output();
|
|
41015
|
+
|
|
41016
|
+
// src/tools/user-input.ts
|
|
41017
|
+
init_i18n();
|
|
41018
|
+
init_output();
|
|
41019
|
+
var CUSTOM_INDEX = -1;
|
|
41020
|
+
function parseSelection(input, optionCount, multiple) {
|
|
41021
|
+
const trimmed = input.trim();
|
|
41022
|
+
if (!trimmed)
|
|
41023
|
+
return null;
|
|
41024
|
+
const parts = trimmed.split(",").map((p) => p.trim());
|
|
41025
|
+
if (!multiple && parts.length > 1)
|
|
41026
|
+
return null;
|
|
41027
|
+
const indexes = [];
|
|
41028
|
+
for (const part of parts) {
|
|
41029
|
+
if (!/^\d+$/.test(part))
|
|
41030
|
+
return null;
|
|
41031
|
+
const idx = Number(part) - 1;
|
|
41032
|
+
if (idx < 0 || idx >= optionCount)
|
|
41033
|
+
return null;
|
|
41034
|
+
if (indexes.includes(idx))
|
|
41035
|
+
return null;
|
|
41036
|
+
indexes.push(idx);
|
|
41037
|
+
}
|
|
41038
|
+
return indexes.length ? indexes : null;
|
|
41039
|
+
}
|
|
41040
|
+
function formatMenu(question, options, opts = {}) {
|
|
41041
|
+
const lines = [question];
|
|
41042
|
+
options.forEach((opt, i) => {
|
|
41043
|
+
lines.push(` [${i + 1}] ${opt.label} — ${opt.description}`);
|
|
41044
|
+
});
|
|
41045
|
+
if (opts.allowCustom) {
|
|
41046
|
+
lines.push(` [${options.length + 1}] ${t("tool.user_input.custom_option")}`);
|
|
41047
|
+
}
|
|
41048
|
+
return lines.join(`
|
|
40433
41049
|
`);
|
|
40434
41050
|
}
|
|
41051
|
+
function choicePrompt(optionCount, multiple) {
|
|
41052
|
+
return multiple ? t("tool.user_input.choice_multiple") : t("tool.user_input.choice_single", { max: optionCount });
|
|
41053
|
+
}
|
|
41054
|
+
|
|
41055
|
+
// src/tools/prompt-io.ts
|
|
41056
|
+
init_i18n();
|
|
41057
|
+
function createPromptIO(deps) {
|
|
41058
|
+
return {
|
|
41059
|
+
async askText(question) {
|
|
41060
|
+
return (await deps.ask(`${question} `)).trim();
|
|
41061
|
+
},
|
|
41062
|
+
async askChoice(question, options, opts = {}) {
|
|
41063
|
+
const multiple = opts.multiple ?? false;
|
|
41064
|
+
const entryCount = options.length + (opts.allowCustom ? 1 : 0);
|
|
41065
|
+
if (entryCount === 0)
|
|
41066
|
+
return [];
|
|
41067
|
+
const customEntry = options.length;
|
|
41068
|
+
deps.print(formatMenu(question, options, opts));
|
|
41069
|
+
for (;; ) {
|
|
41070
|
+
const answer = await deps.ask(choicePrompt(entryCount, multiple));
|
|
41071
|
+
const parsed = parseSelection(answer, entryCount, multiple);
|
|
41072
|
+
if (parsed) {
|
|
41073
|
+
return parsed.map((i) => opts.allowCustom && i === customEntry ? CUSTOM_INDEX : i);
|
|
41074
|
+
}
|
|
41075
|
+
deps.print(t("tool.user_input.invalid"));
|
|
41076
|
+
}
|
|
41077
|
+
}
|
|
41078
|
+
};
|
|
41079
|
+
}
|
|
40435
41080
|
|
|
40436
41081
|
// src/cli/repl.ts
|
|
40437
41082
|
function formatContextBar(used, limit, compactions, quality) {
|
|
40438
41083
|
const pct = Math.min(100, Math.round(used / limit * 100));
|
|
40439
41084
|
const barLen = 20;
|
|
40440
41085
|
const filled = Math.round(pct / 100 * barLen);
|
|
40441
|
-
const bar =
|
|
40442
|
-
const pctStr = pct >= 75 ?
|
|
40443
|
-
let line = ` ${bar} ${pctStr} ${
|
|
41086
|
+
const bar = pc.green("█".repeat(filled)) + pc.dim("░".repeat(barLen - filled));
|
|
41087
|
+
const pctStr = pct >= 75 ? pc.yellow(`${pct}%`) : pc.dim(`${pct}%`);
|
|
41088
|
+
let line = ` ${bar} ${pctStr} ${pc.dim(`(${used} / ${limit} tokens)`)}`;
|
|
40444
41089
|
if (compactions !== undefined) {
|
|
40445
|
-
line +=
|
|
41090
|
+
line += pc.dim(` compactions: ${compactions}`);
|
|
40446
41091
|
}
|
|
40447
41092
|
if (quality !== undefined) {
|
|
40448
|
-
const qColor = quality >= 70 ?
|
|
41093
|
+
const qColor = quality >= 70 ? pc.green : quality >= 40 ? pc.yellow : pc.red;
|
|
40449
41094
|
line += ` ${qColor(`quality: ${quality}%`)}`;
|
|
40450
41095
|
}
|
|
40451
41096
|
return line;
|
|
@@ -40463,7 +41108,8 @@ function createHostBridge(opts) {
|
|
|
40463
41108
|
interrupt() {
|
|
40464
41109
|
if (opts.isBusy())
|
|
40465
41110
|
opts.interruptRun();
|
|
40466
|
-
}
|
|
41111
|
+
},
|
|
41112
|
+
subscribeOutput: (fn) => defaultOutputBus.subscribe(fn)
|
|
40467
41113
|
};
|
|
40468
41114
|
}
|
|
40469
41115
|
|
|
@@ -40484,6 +41130,8 @@ class Repl {
|
|
|
40484
41130
|
pendingClipboardImage = null;
|
|
40485
41131
|
exitOnClose = false;
|
|
40486
41132
|
execModule;
|
|
41133
|
+
promptPresented = false;
|
|
41134
|
+
runHandledPrompt = false;
|
|
40487
41135
|
rl;
|
|
40488
41136
|
agent;
|
|
40489
41137
|
config;
|
|
@@ -40492,9 +41140,13 @@ class Repl {
|
|
|
40492
41140
|
pluginManager;
|
|
40493
41141
|
logger;
|
|
40494
41142
|
slog;
|
|
41143
|
+
sessionOutput;
|
|
40495
41144
|
envReport;
|
|
40496
41145
|
contextProbe;
|
|
40497
|
-
|
|
41146
|
+
output;
|
|
41147
|
+
promptSink;
|
|
41148
|
+
promptIO;
|
|
41149
|
+
constructor(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger4, exitOnClose, envReport, historyPath, execModule, contextProbe, output) {
|
|
40498
41150
|
this.agent = agent;
|
|
40499
41151
|
this.config = config;
|
|
40500
41152
|
this.exitOnClose = exitOnClose === true;
|
|
@@ -40506,37 +41158,59 @@ class Repl {
|
|
|
40506
41158
|
this.contextProbe = contextProbe;
|
|
40507
41159
|
this.execModule = execModule;
|
|
40508
41160
|
this.slog = new SessionLogger(sessionManager, logger4);
|
|
41161
|
+
this.bindSessionOutput();
|
|
40509
41162
|
this.configDir = configDir || join55(homedir18(), ".mma");
|
|
40510
41163
|
this.baseDir = baseDir || process.cwd();
|
|
40511
41164
|
this.noAgentsMd = noAgentsMd === true;
|
|
40512
41165
|
this.historyPath = historyPath ?? join55(homedir18(), ".mma", "repl-history");
|
|
40513
41166
|
this.loadHistory();
|
|
40514
|
-
|
|
40515
|
-
|
|
40516
|
-
|
|
40517
|
-
|
|
40518
|
-
|
|
40519
|
-
|
|
40520
|
-
|
|
40521
|
-
|
|
40522
|
-
|
|
40523
|
-
|
|
40524
|
-
|
|
40525
|
-
|
|
40526
|
-
|
|
40527
|
-
|
|
40528
|
-
|
|
40529
|
-
|
|
40530
|
-
|
|
40531
|
-
|
|
40532
|
-
|
|
40533
|
-
|
|
40534
|
-
|
|
40535
|
-
|
|
40536
|
-
|
|
40537
|
-
|
|
41167
|
+
const editorCompleter = (line) => {
|
|
41168
|
+
const [matches, partial] = this.completer.complete(line);
|
|
41169
|
+
if (matches.length > 0)
|
|
41170
|
+
return [matches, partial];
|
|
41171
|
+
return [[], line];
|
|
41172
|
+
};
|
|
41173
|
+
if (process.stdin.isTTY) {
|
|
41174
|
+
this.rl = new LineEditor({
|
|
41175
|
+
input: process.stdin,
|
|
41176
|
+
output: process.stdout,
|
|
41177
|
+
prompt: this.inputPrompt(),
|
|
41178
|
+
history: this.history,
|
|
41179
|
+
historySize: this.maxHistory,
|
|
41180
|
+
completer: editorCompleter
|
|
41181
|
+
});
|
|
41182
|
+
} else {
|
|
41183
|
+
this.rl = readline2.createInterface({
|
|
41184
|
+
input: process.stdin,
|
|
41185
|
+
output: process.stdout,
|
|
41186
|
+
prompt: this.inputPrompt(),
|
|
41187
|
+
history: this.history,
|
|
41188
|
+
historySize: this.maxHistory,
|
|
41189
|
+
tabSize: 2,
|
|
41190
|
+
completer: editorCompleter
|
|
41191
|
+
});
|
|
41192
|
+
}
|
|
41193
|
+
this.output = output ?? getDefaultChannel();
|
|
41194
|
+
this.promptSink = {
|
|
41195
|
+
isActive: () => this.rl instanceof LineEditor && this.promptPresented && !this.agentRunning && !this.inputLocked,
|
|
41196
|
+
printAbove: (text) => {
|
|
41197
|
+
if (this.rl instanceof LineEditor) {
|
|
41198
|
+
this.rl.printAbove(text);
|
|
41199
|
+
return;
|
|
41200
|
+
}
|
|
41201
|
+
writeNonTtyLine(text);
|
|
41202
|
+
},
|
|
41203
|
+
clearScreen: () => {
|
|
41204
|
+
if (this.rl instanceof LineEditor)
|
|
41205
|
+
this.rl.clearScreen();
|
|
40538
41206
|
}
|
|
41207
|
+
};
|
|
41208
|
+
this.output.attachPrompt(this.promptSink);
|
|
41209
|
+
this.promptIO = createPromptIO({
|
|
41210
|
+
ask: (prompt) => this.askViaEditor(prompt),
|
|
41211
|
+
print: (line) => this.output.writeLine(line)
|
|
40539
41212
|
});
|
|
41213
|
+
this.agent.setPromptIO?.(this.promptIO);
|
|
40540
41214
|
registerAllCommands(this);
|
|
40541
41215
|
this.setupCompleter();
|
|
40542
41216
|
this.setupListeners();
|
|
@@ -40560,6 +41234,10 @@ class Repl {
|
|
|
40560
41234
|
interruptRun: () => this.agent.shutdown()
|
|
40561
41235
|
}));
|
|
40562
41236
|
}
|
|
41237
|
+
bindSessionOutput() {
|
|
41238
|
+
this.sessionOutput?.dispose();
|
|
41239
|
+
this.sessionOutput = this.sessionManager ? new SessionOutputSink(defaultOutputBus, this.sessionManager) : undefined;
|
|
41240
|
+
}
|
|
40563
41241
|
async reload() {
|
|
40564
41242
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
40565
41243
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -40572,10 +41250,12 @@ class Repl {
|
|
|
40572
41250
|
Object.assign(this.config, freshConfig);
|
|
40573
41251
|
const result = await bootstrap2(this.configDir, this.baseDir, false, false);
|
|
40574
41252
|
this.agent = result.agent;
|
|
41253
|
+
this.agent.setPromptIO?.(this.promptIO);
|
|
40575
41254
|
this.sessionManager = result.sessionManager;
|
|
40576
41255
|
this.skillsModule = result.skillsModule;
|
|
40577
41256
|
this.pluginManager = result.pluginManager;
|
|
40578
41257
|
this.execModule = result.execModule;
|
|
41258
|
+
this.bindSessionOutput();
|
|
40579
41259
|
this.attachHostBridge(result.pluginManager);
|
|
40580
41260
|
this.setupCompleter();
|
|
40581
41261
|
}
|
|
@@ -40591,9 +41271,14 @@ class Repl {
|
|
|
40591
41271
|
}
|
|
40592
41272
|
}
|
|
40593
41273
|
saveHistory() {
|
|
40594
|
-
|
|
40595
|
-
|
|
41274
|
+
try {
|
|
41275
|
+
mkdirSync23(dirname25(this.historyPath), { recursive: true });
|
|
41276
|
+
const allHistory = this.history.slice(-this.maxHistory);
|
|
41277
|
+
writeFileSync24(this.historyPath, allHistory.join(`
|
|
40596
41278
|
`), "utf-8");
|
|
41279
|
+
} catch (e) {
|
|
41280
|
+
this.logger?.debug(`Failed to save REPL history: ${e.message}`);
|
|
41281
|
+
}
|
|
40597
41282
|
}
|
|
40598
41283
|
setupCompleter() {
|
|
40599
41284
|
this.completer.reset();
|
|
@@ -40659,16 +41344,13 @@ class Repl {
|
|
|
40659
41344
|
if (fullInput) {
|
|
40660
41345
|
if (fullInput.startsWith("/")) {
|
|
40661
41346
|
await this.executeCommand(fullInput);
|
|
41347
|
+
this.afterCommand();
|
|
40662
41348
|
} else {
|
|
40663
41349
|
await this.runAgent(fullInput);
|
|
40664
41350
|
}
|
|
40665
41351
|
}
|
|
40666
|
-
if (this.running) {
|
|
40667
|
-
this.rl.setPrompt(pc2.cyan(t("repl.you")));
|
|
40668
|
-
this.rl.prompt();
|
|
40669
|
-
}
|
|
40670
41352
|
} else {
|
|
40671
|
-
this.rl.setPrompt(
|
|
41353
|
+
this.rl.setPrompt(this.inputPrompt(true));
|
|
40672
41354
|
this.rl.prompt();
|
|
40673
41355
|
}
|
|
40674
41356
|
return;
|
|
@@ -40676,24 +41358,21 @@ class Repl {
|
|
|
40676
41358
|
if (this.isMultiLineInput(trimmed)) {
|
|
40677
41359
|
inMultiLine = true;
|
|
40678
41360
|
multiLineBuffer = trimmed;
|
|
40679
|
-
this.rl.setPrompt(
|
|
41361
|
+
this.rl.setPrompt(this.inputPrompt(true));
|
|
40680
41362
|
this.rl.prompt();
|
|
40681
41363
|
return;
|
|
40682
41364
|
}
|
|
40683
41365
|
if (!trimmed) {
|
|
40684
|
-
this.rl.setPrompt(
|
|
41366
|
+
this.rl.setPrompt(this.inputPrompt());
|
|
40685
41367
|
this.rl.prompt();
|
|
40686
41368
|
return;
|
|
40687
41369
|
}
|
|
40688
41370
|
if (trimmed.startsWith("/")) {
|
|
40689
41371
|
await this.executeCommand(trimmed);
|
|
41372
|
+
this.afterCommand();
|
|
40690
41373
|
} else {
|
|
40691
41374
|
await this.runAgent(trimmed);
|
|
40692
41375
|
}
|
|
40693
|
-
if (this.running) {
|
|
40694
|
-
this.rl.setPrompt(pc2.cyan(t("repl.you")));
|
|
40695
|
-
this.rl.prompt();
|
|
40696
|
-
}
|
|
40697
41376
|
});
|
|
40698
41377
|
this.rl.on("close", () => {
|
|
40699
41378
|
this.running = false;
|
|
@@ -40721,7 +41400,7 @@ class Repl {
|
|
|
40721
41400
|
}
|
|
40722
41401
|
Repl.sigintHandler = () => {
|
|
40723
41402
|
if (this.agentRunning) {
|
|
40724
|
-
|
|
41403
|
+
this.output.writeLine(pc.yellow(t("repl.ctrl_c_interrupt")));
|
|
40725
41404
|
this.agent.shutdown();
|
|
40726
41405
|
this.agentRunning = false;
|
|
40727
41406
|
if (forceExitTimer)
|
|
@@ -40733,6 +41412,35 @@ class Repl {
|
|
|
40733
41412
|
};
|
|
40734
41413
|
process.on("SIGINT", Repl.sigintHandler);
|
|
40735
41414
|
}
|
|
41415
|
+
presentPrompt() {
|
|
41416
|
+
if (!this.running)
|
|
41417
|
+
return;
|
|
41418
|
+
this.rl.setPrompt(this.inputPrompt());
|
|
41419
|
+
this.rl.prompt();
|
|
41420
|
+
this.promptPresented = true;
|
|
41421
|
+
}
|
|
41422
|
+
reasoningLabel() {
|
|
41423
|
+
const mode = this.config.reasoning?.mode ?? "default";
|
|
41424
|
+
if (mode !== "auto")
|
|
41425
|
+
return this.agent.reasoningLevel ?? mode;
|
|
41426
|
+
const rs = this.agent.reasoningState;
|
|
41427
|
+
const cooldown = this.config.reasoning?.overrideCooldown ?? 0;
|
|
41428
|
+
const transientActive = rs.overrideIteration >= 0 && this.agent.currentIteration - rs.overrideIteration <= cooldown;
|
|
41429
|
+
if (rs.manual || transientActive)
|
|
41430
|
+
return `auto→${this.agent.reasoningLevel}`;
|
|
41431
|
+
return "auto";
|
|
41432
|
+
}
|
|
41433
|
+
inputPrompt(continuation = false) {
|
|
41434
|
+
const key = continuation ? "repl.you_reasoning_cont" : "repl.you_reasoning";
|
|
41435
|
+
return pc.cyan(t(key, { level: this.reasoningLabel() }));
|
|
41436
|
+
}
|
|
41437
|
+
afterCommand() {
|
|
41438
|
+
if (this.runHandledPrompt) {
|
|
41439
|
+
this.runHandledPrompt = false;
|
|
41440
|
+
return;
|
|
41441
|
+
}
|
|
41442
|
+
this.presentPrompt();
|
|
41443
|
+
}
|
|
40736
41444
|
handleSpecialKey(str, key) {
|
|
40737
41445
|
if (key.name === "escape") {
|
|
40738
41446
|
const escBytes = key.sequence ? (key.sequence.match(/\x1b/g) || []).length : 1;
|
|
@@ -40742,9 +41450,8 @@ class Repl {
|
|
|
40742
41450
|
if (escBytes >= 2 || withinWindow) {
|
|
40743
41451
|
this.lastEscTime = 0;
|
|
40744
41452
|
if (this.agentRunning) {
|
|
40745
|
-
|
|
40746
|
-
${t("repl.interrupt")}
|
|
40747
|
-
`));
|
|
41453
|
+
this.output.writeLine(pc.yellow(`
|
|
41454
|
+
${t("repl.interrupt")}`));
|
|
40748
41455
|
this.agent.shutdown();
|
|
40749
41456
|
}
|
|
40750
41457
|
}
|
|
@@ -40764,13 +41471,13 @@ ${t("repl.interrupt")}
|
|
|
40764
41471
|
const { dataUrl } = await bufferToDataUrl2(clipBuf);
|
|
40765
41472
|
this.pendingClipboardImage = dataUrl;
|
|
40766
41473
|
const sizeKb = Math.round(dataUrl.length * 3 / 4 / 1024);
|
|
40767
|
-
|
|
41474
|
+
this.output.writeLine(pc.green(`
|
|
40768
41475
|
${t("image.attached", { source: "clipboard", size: `${sizeKb} KB` })}`));
|
|
40769
41476
|
if (this.rl instanceof LineEditor)
|
|
40770
41477
|
this.rl.reset();
|
|
40771
41478
|
this.rl.prompt();
|
|
40772
41479
|
} else {
|
|
40773
|
-
|
|
41480
|
+
this.output.writeLine(pc.yellow(`
|
|
40774
41481
|
${t("image.clipboard_empty")}`));
|
|
40775
41482
|
if (this.rl instanceof LineEditor)
|
|
40776
41483
|
this.rl.reset();
|
|
@@ -40803,13 +41510,19 @@ ${t("image.clipboard_empty")}`));
|
|
|
40803
41510
|
this.pendingClipboardImage = null;
|
|
40804
41511
|
}
|
|
40805
41512
|
this.logger?.logREPL("user", input);
|
|
40806
|
-
|
|
41513
|
+
this.promptPresented = false;
|
|
41514
|
+
if (this.rl instanceof LineEditor) {
|
|
41515
|
+
this.rl.suspendFrame();
|
|
41516
|
+
this.rl.setInputEnabled(false);
|
|
40807
41517
|
this.rl.reset();
|
|
40808
|
-
|
|
40809
|
-
|
|
41518
|
+
}
|
|
41519
|
+
this.output.beginStreaming();
|
|
41520
|
+
this.output.writeRaw(`\r${divider()}
|
|
41521
|
+
${pc.green(t("repl.agent"))}`);
|
|
40810
41522
|
const renderer = new Renderer({
|
|
40811
41523
|
spinner: this.config.ui?.spinner ?? true,
|
|
40812
|
-
baseDir: this.baseDir
|
|
41524
|
+
baseDir: this.baseDir,
|
|
41525
|
+
channel: this.output
|
|
40813
41526
|
});
|
|
40814
41527
|
renderer.showLoader();
|
|
40815
41528
|
const result = await this.agent.run(input, (c) => renderer.text(c), (m) => renderer.meta(m), (ev) => {
|
|
@@ -40832,18 +41545,26 @@ ${t("image.clipboard_empty")}`));
|
|
|
40832
41545
|
if (result.provider && result.model) {
|
|
40833
41546
|
renderer.footer(result.model, result.provider, result.llmDurationMs ?? result.durationMs ?? 0);
|
|
40834
41547
|
}
|
|
40835
|
-
|
|
40836
|
-
`);
|
|
41548
|
+
this.output.writeLine("");
|
|
40837
41549
|
this.logger?.logREPL(result.success ? "assistant" : "system", result.text?.slice(0, 400) || result.error || "");
|
|
40838
41550
|
if (!result.success) {
|
|
40839
|
-
|
|
41551
|
+
this.output.writeLine(pc.red(`${t("error.prefix")}${result.error}`), "stderr");
|
|
40840
41552
|
}
|
|
40841
41553
|
this.showContextBar(result);
|
|
40842
|
-
|
|
40843
|
-
|
|
40844
|
-
`);
|
|
41554
|
+
this.output.writeLine(`
|
|
41555
|
+
${divider()}`);
|
|
40845
41556
|
} finally {
|
|
40846
41557
|
this.agentRunning = false;
|
|
41558
|
+
this.output.endStreaming();
|
|
41559
|
+
if (this.rl instanceof LineEditor) {
|
|
41560
|
+
this.rl.setInputEnabled(true);
|
|
41561
|
+
this.rl.setPrompt(this.inputPrompt());
|
|
41562
|
+
this.rl.resumeFrame();
|
|
41563
|
+
this.promptPresented = true;
|
|
41564
|
+
} else {
|
|
41565
|
+
this.presentPrompt();
|
|
41566
|
+
}
|
|
41567
|
+
this.runHandledPrompt = true;
|
|
40847
41568
|
}
|
|
40848
41569
|
}
|
|
40849
41570
|
renderPlan(renderer) {
|
|
@@ -40869,21 +41590,44 @@ ${t("image.clipboard_empty")}`));
|
|
|
40869
41590
|
this.inputLocked = false;
|
|
40870
41591
|
}
|
|
40871
41592
|
}
|
|
41593
|
+
async askViaEditor(prompt) {
|
|
41594
|
+
const editor = this.rl instanceof LineEditor ? this.rl : null;
|
|
41595
|
+
const wasSuspended = editor ? editor.isFrameSuspended() : true;
|
|
41596
|
+
const wasEnabled = editor ? editor.isInputEnabled() : false;
|
|
41597
|
+
this.output.beginModal();
|
|
41598
|
+
if (editor) {
|
|
41599
|
+
editor.setInputEnabled(true);
|
|
41600
|
+
editor.resumeFrame();
|
|
41601
|
+
}
|
|
41602
|
+
try {
|
|
41603
|
+
return await new Promise((resolve24) => this.rl.question(prompt, resolve24));
|
|
41604
|
+
} finally {
|
|
41605
|
+
if (editor) {
|
|
41606
|
+
editor.setInputEnabled(wasEnabled);
|
|
41607
|
+
if (wasSuspended)
|
|
41608
|
+
editor.suspendFrame();
|
|
41609
|
+
else
|
|
41610
|
+
editor.resumeFrame();
|
|
41611
|
+
}
|
|
41612
|
+
this.output.endModal();
|
|
41613
|
+
}
|
|
41614
|
+
}
|
|
40872
41615
|
async executeCommand(input) {
|
|
40873
41616
|
const parts = input.split(/\s+/);
|
|
40874
41617
|
const name = parts[0].slice(1);
|
|
40875
41618
|
const args = parts.slice(1);
|
|
41619
|
+
this.runHandledPrompt = false;
|
|
40876
41620
|
const cmd = this.commands.get(name);
|
|
40877
41621
|
if (!cmd) {
|
|
40878
|
-
|
|
41622
|
+
this.output.writeLine(`${pc.red(t("cli.unknown_cmd", { name }))} ${t("cli.help_hint")}`);
|
|
40879
41623
|
return;
|
|
40880
41624
|
}
|
|
40881
41625
|
try {
|
|
40882
41626
|
await cmd.action(args);
|
|
40883
41627
|
} catch (err) {
|
|
40884
|
-
|
|
41628
|
+
this.output.writeLine(pc.red(t("error.command_error", {
|
|
40885
41629
|
message: errMsg(err)
|
|
40886
|
-
})));
|
|
41630
|
+
})), "stderr");
|
|
40887
41631
|
}
|
|
40888
41632
|
}
|
|
40889
41633
|
showHelp() {
|
|
@@ -40905,15 +41649,15 @@ ${t("image.clipboard_empty")}`));
|
|
|
40905
41649
|
}
|
|
40906
41650
|
if (cmds.length === 0)
|
|
40907
41651
|
continue;
|
|
40908
|
-
|
|
41652
|
+
this.output.writeLine(pc.bold(t(`repl.group.${groupKey}`)));
|
|
40909
41653
|
for (const cmd of cmds) {
|
|
40910
|
-
const aliases = cmd.aliases?.length ? ` (${
|
|
40911
|
-
|
|
41654
|
+
const aliases = cmd.aliases?.length ? ` (${pc.dim(cmd.aliases.join(", "))})` : "";
|
|
41655
|
+
this.output.writeLine(` ${pc.cyan("/" + cmd.name)}${aliases} ${pc.dim(cmd.description)}`);
|
|
40912
41656
|
if (cmd.usage) {
|
|
40913
|
-
|
|
41657
|
+
this.output.writeLine(` ${pc.dim(cmd.usage)}`);
|
|
40914
41658
|
}
|
|
40915
41659
|
}
|
|
40916
|
-
|
|
41660
|
+
this.output.writeLine("");
|
|
40917
41661
|
}
|
|
40918
41662
|
}
|
|
40919
41663
|
lastCompactionShown = 0;
|
|
@@ -40923,24 +41667,24 @@ ${t("image.clipboard_empty")}`));
|
|
|
40923
41667
|
}
|
|
40924
41668
|
const ui = this.config.ui;
|
|
40925
41669
|
if (ui?.showContextStats) {
|
|
40926
|
-
|
|
41670
|
+
this.output.writeLine("");
|
|
40927
41671
|
const ctxLine = formatContextBar(result.contextUsed, result.contextLimit, result.compactionCount, result.contextQuality);
|
|
40928
|
-
|
|
41672
|
+
this.output.writeLine(ctxLine);
|
|
40929
41673
|
if (result.totalTokens !== undefined && result.totalTokens > 0) {
|
|
40930
|
-
const apiLine =
|
|
40931
|
-
|
|
41674
|
+
const apiLine = pc.dim(` API: ${result.promptTokens} prompt + ${result.completionTokens} completion = ${result.totalTokens} total`);
|
|
41675
|
+
this.output.writeLine(apiLine);
|
|
40932
41676
|
}
|
|
40933
41677
|
if (result.totalCost !== undefined && result.totalCost > 0) {
|
|
40934
|
-
|
|
41678
|
+
this.output.writeLine(pc.yellow(` ${t("repl.cost", { cost: formatCost(result.totalCost) })}`));
|
|
40935
41679
|
}
|
|
40936
41680
|
const cacheLine = formatCacheLine(result.cache);
|
|
40937
41681
|
if (cacheLine) {
|
|
40938
|
-
|
|
41682
|
+
this.output.writeLine(pc.dim(` ${cacheLine}`));
|
|
40939
41683
|
}
|
|
40940
41684
|
} else if (ui?.showCompaction && result.compactionCount !== undefined) {
|
|
40941
41685
|
if (result.compactionCount > this.lastCompactionShown) {
|
|
40942
41686
|
this.lastCompactionShown = result.compactionCount;
|
|
40943
|
-
|
|
41687
|
+
this.output.writeLine(pc.dim(`
|
|
40944
41688
|
⟳ Context compacted (${result.compactionCount})`));
|
|
40945
41689
|
}
|
|
40946
41690
|
}
|
|
@@ -40949,42 +41693,41 @@ ${t("image.clipboard_empty")}`));
|
|
|
40949
41693
|
this.running = true;
|
|
40950
41694
|
const info = [];
|
|
40951
41695
|
const row = (label, value) => {
|
|
40952
|
-
info.push(` ${
|
|
41696
|
+
info.push(` ${pc.yellow(label)} ${value}`);
|
|
40953
41697
|
};
|
|
40954
41698
|
const ctx = this.config.contextWindow;
|
|
40955
41699
|
const sysBudget = Math.floor(ctx * this.config.contextBudget.systemPrompt);
|
|
40956
41700
|
const resBudget = Math.floor(ctx * this.config.contextBudget.responseReserve);
|
|
40957
41701
|
const histBudget = ctx - sysBudget - resBudget;
|
|
40958
|
-
row(t("repl.model"),
|
|
40959
|
-
row(t("repl.provider"), `${this.config.provider.type} → ${
|
|
40960
|
-
row(t("repl.context"), `${
|
|
41702
|
+
row(t("repl.model"), pc.white(this.config.model));
|
|
41703
|
+
row(t("repl.provider"), `${this.config.provider.type} → ${pc.dim(this.config.provider.baseUrl)}`);
|
|
41704
|
+
row(t("repl.context"), `${pc.white(String(ctx))} ${pc.dim(`(sys:${sysBudget} res:${resBudget} hist:${histBudget})`)}`);
|
|
40961
41705
|
const si = this.agent.getSystemPromptInfo();
|
|
40962
|
-
row(t("repl.sysprompt_label"),
|
|
41706
|
+
row(t("repl.sysprompt_label"), pc.dim(t("repl.sysprompt_size", { used: si.tokenCount, budget: sysBudget })));
|
|
40963
41707
|
if (this.skillsModule) {
|
|
40964
41708
|
const budget = this.skillsModule.getBudget();
|
|
40965
|
-
row(t("repl.skills_label"), `${
|
|
41709
|
+
row(t("repl.skills_label"), `${pc.white(String(this.skillsModule.getAvailable().length))} available, ${pc.dim(`budget: ${budget.total} tokens`)}`);
|
|
40966
41710
|
}
|
|
40967
41711
|
if (this.pluginManager) {
|
|
40968
41712
|
const infos = this.pluginManager.getPluginInfos().filter(({ plugin: plugin3 }) => !plugin3.isBuiltin);
|
|
40969
41713
|
if (infos.length > 0) {
|
|
40970
41714
|
const pluginNames = infos.map(({ plugin: plugin3, source }) => {
|
|
40971
|
-
const version3 = plugin3.version ? `${
|
|
40972
|
-
const origin = source ?
|
|
41715
|
+
const version3 = plugin3.version ? `${pc.dim(plugin3.version)}` : "";
|
|
41716
|
+
const origin = source ? pc.dim(` [${source}]`) : "";
|
|
40973
41717
|
return `${plugin3.name}${version3}${origin}`;
|
|
40974
41718
|
}).join(", ");
|
|
40975
|
-
row(t("repl.plugins_label"), `${
|
|
41719
|
+
row(t("repl.plugins_label"), `${pc.white(String(infos.length))} active ${pc.dim(`(${pluginNames})`)}`);
|
|
40976
41720
|
}
|
|
40977
41721
|
}
|
|
40978
41722
|
const mcpServers = this.config.mcpServers || {};
|
|
40979
41723
|
const enabledServers = Object.entries(mcpServers).filter(([, s]) => s.enabled !== false);
|
|
40980
41724
|
if (enabledServers.length > 0) {
|
|
40981
41725
|
const names = enabledServers.map(([name]) => name).join(", ");
|
|
40982
|
-
row(t("repl.mcp_label"), `${
|
|
41726
|
+
row(t("repl.mcp_label"), `${pc.white(String(enabledServers.length))} ${pc.dim(`(${names})`)}`);
|
|
40983
41727
|
}
|
|
40984
|
-
|
|
40985
|
-
row(t("repl.work_dir"), pc2.dim(cwd));
|
|
41728
|
+
row(t("repl.work_dir"), pc.dim(this.baseDir));
|
|
40986
41729
|
if (this.noAgentsMd) {
|
|
40987
|
-
row(t("repl.agents_label"),
|
|
41730
|
+
row(t("repl.agents_label"), pc.red(t("repl.disabled")));
|
|
40988
41731
|
} else {
|
|
40989
41732
|
const agentsMdCandidates = [
|
|
40990
41733
|
join55(this.baseDir, "AGENTS.md"),
|
|
@@ -40994,42 +41737,41 @@ ${t("image.clipboard_empty")}`));
|
|
|
40994
41737
|
const foundAgents = agentsMdCandidates.filter((p) => existsSync60(p));
|
|
40995
41738
|
if (foundAgents.length > 0) {
|
|
40996
41739
|
for (const p of foundAgents) {
|
|
40997
|
-
row(t("repl.agents_label"),
|
|
41740
|
+
row(t("repl.agents_label"), pc.dim(p));
|
|
40998
41741
|
}
|
|
40999
41742
|
} else {
|
|
41000
|
-
row(t("repl.agents_label"),
|
|
41743
|
+
row(t("repl.agents_label"), pc.dim(t("repl.not_found")));
|
|
41001
41744
|
}
|
|
41002
41745
|
}
|
|
41003
41746
|
const meta = this.sessionManager?.getActiveMeta();
|
|
41004
41747
|
if (meta) {
|
|
41005
41748
|
const sessionPath = join55(this.configDir, "sessions", meta.id);
|
|
41006
|
-
row(t("repl.session_label"), `${
|
|
41749
|
+
row(t("repl.session_label"), `${pc.cyan(meta.name)} ${pc.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc.dim(sessionPath)}`);
|
|
41007
41750
|
}
|
|
41008
41751
|
const isTty2 = process.stdout.isTTY === true;
|
|
41009
41752
|
const lspEnabled = isTty2 && (this.config.lsp ?? DEFAULT_LSP_CONFIG).enabled !== false;
|
|
41010
41753
|
for (const line of info) {
|
|
41011
|
-
|
|
41754
|
+
this.output.writeLine(pc.dim(line).trimEnd());
|
|
41012
41755
|
}
|
|
41013
|
-
|
|
41756
|
+
this.output.writeLine("");
|
|
41014
41757
|
try {
|
|
41015
41758
|
const { existsSync: exists } = await import("fs");
|
|
41016
41759
|
const { join: pathJoin } = await import("path");
|
|
41017
41760
|
const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
41018
41761
|
const legacyPath = pathJoin(this.configDir, "config.json");
|
|
41019
41762
|
if (exists(legacyPath) && !hasDomainFiles3(this.configDir)) {
|
|
41020
|
-
|
|
41021
|
-
|
|
41763
|
+
this.output.writeLine(pc.yellow(` ${t("config.legacy_hint")}`));
|
|
41764
|
+
this.output.writeLine("");
|
|
41022
41765
|
}
|
|
41023
41766
|
} catch {}
|
|
41024
41767
|
this.rl.prompt();
|
|
41768
|
+
this.promptPresented = true;
|
|
41025
41769
|
if (lspEnabled) {
|
|
41026
41770
|
this.probeLspBanner().then((lspSummary) => {
|
|
41027
41771
|
if (lspSummary) {
|
|
41028
|
-
const line = `${
|
|
41029
|
-
|
|
41030
|
-
${line}
|
|
41031
|
-
`);
|
|
41032
|
-
this.rl.prompt();
|
|
41772
|
+
const line = `${pc.green(t("repl.agent"))}${pc.yellow(t("repl.lsp_label"))} ${lspSummary}`;
|
|
41773
|
+
this.output.writeLine(`${divider()}
|
|
41774
|
+
${line}`);
|
|
41033
41775
|
}
|
|
41034
41776
|
}).catch(() => {});
|
|
41035
41777
|
}
|
|
@@ -41040,7 +41782,7 @@ ${line}
|
|
|
41040
41782
|
})).filter((x) => Boolean(x.provider))), { timeoutMs: 5000 }).then((results) => {
|
|
41041
41783
|
for (const r of results) {
|
|
41042
41784
|
if (!r.ok && r.name !== this.config.provider.active) {
|
|
41043
|
-
|
|
41785
|
+
this.output.writeLine(formatWarning(t("repl.provider_down", { name: r.name, error: r.error ?? "" })));
|
|
41044
41786
|
}
|
|
41045
41787
|
}
|
|
41046
41788
|
}).catch(() => {});
|
|
@@ -41054,12 +41796,10 @@ ${line}
|
|
|
41054
41796
|
type: "context_probe",
|
|
41055
41797
|
content: `model=${probe.model} actual=${probe.actual} configured=${this.config.contextWindow}`
|
|
41056
41798
|
});
|
|
41057
|
-
const line = probe.actual < this.config.contextWindow ? `${
|
|
41799
|
+
const line = probe.actual < this.config.contextWindow ? `${pc.yellow("⚠")} ${t("repl.context_probe_small", { model: probe.model, actual: probe.actual, configured: this.config.contextWindow })}` : probe.actual > this.config.contextWindow ? `${pc.dim(t("repl.context_probe_big", { model: probe.model, actual: probe.actual }))}` : null;
|
|
41058
41800
|
if (line) {
|
|
41059
|
-
|
|
41060
|
-
${line}
|
|
41061
|
-
`);
|
|
41062
|
-
this.rl.prompt();
|
|
41801
|
+
this.output.writeLine(`${divider()}
|
|
41802
|
+
${line}`);
|
|
41063
41803
|
}
|
|
41064
41804
|
}).catch(() => {});
|
|
41065
41805
|
}
|
|
@@ -41085,21 +41825,23 @@ ${line}
|
|
|
41085
41825
|
return null;
|
|
41086
41826
|
const parts = [];
|
|
41087
41827
|
for (const r of summary.ok) {
|
|
41088
|
-
parts.push(
|
|
41828
|
+
parts.push(pc.green(`✓ ${r.language}${pc.dim(` (${(r.durationMs / 1000).toFixed(1)}s)`)}`));
|
|
41089
41829
|
}
|
|
41090
41830
|
for (const r of summary.failed) {
|
|
41091
41831
|
const reason = r.error?.includes("timeout") ? t("repl.lsp_timeout") : t("repl.lsp_failed");
|
|
41092
|
-
parts.push(
|
|
41832
|
+
parts.push(pc.red(`✗ ${r.language}${pc.dim(` — ${reason}`)}`));
|
|
41093
41833
|
}
|
|
41094
41834
|
return parts.join(" ");
|
|
41095
41835
|
} catch {
|
|
41096
|
-
return
|
|
41836
|
+
return pc.yellow(t("repl.lsp_unknown"));
|
|
41097
41837
|
}
|
|
41098
41838
|
}
|
|
41099
41839
|
stop() {
|
|
41100
41840
|
this.running = false;
|
|
41101
41841
|
this.saveHistory();
|
|
41102
41842
|
this.agent.shutdown();
|
|
41843
|
+
this.sessionOutput?.dispose();
|
|
41844
|
+
this.sessionOutput = undefined;
|
|
41103
41845
|
this.logger?.closeSessionLog();
|
|
41104
41846
|
this.rl.close();
|
|
41105
41847
|
}
|
|
@@ -41109,38 +41851,139 @@ ${line}
|
|
|
41109
41851
|
init_i18n();
|
|
41110
41852
|
init_colors();
|
|
41111
41853
|
init_prices();
|
|
41112
|
-
|
|
41854
|
+
init_output();
|
|
41855
|
+
function printRunResult(result, flush, channel = getDefaultChannel()) {
|
|
41113
41856
|
flush();
|
|
41114
41857
|
if (result.success) {
|
|
41115
41858
|
if (result.totalCost !== undefined && result.totalCost > 0) {
|
|
41116
|
-
|
|
41859
|
+
channel.writeLine(pc.dim(`${t("repl.cost", { cost: formatCost(result.totalCost) })}`));
|
|
41117
41860
|
if (result.costBreakdown && result.costBreakdown.length > 1) {
|
|
41118
41861
|
const parts = result.costBreakdown.map((e) => `${e.provider} ${formatCost(e.cost)}`);
|
|
41119
|
-
|
|
41862
|
+
channel.writeLine(pc.dim(` ${t("repl.cost_breakdown", { breakdown: parts.join(", ") })}`));
|
|
41120
41863
|
}
|
|
41121
41864
|
} else if (result.totalTokens !== undefined && result.totalTokens > 0) {
|
|
41122
|
-
|
|
41865
|
+
channel.writeLine(pc.dim(`${t("repl.tokens", { tokens: result.totalTokens })}`));
|
|
41123
41866
|
}
|
|
41124
41867
|
const cacheLine = formatCacheLine(result.cache);
|
|
41125
41868
|
if (cacheLine) {
|
|
41126
|
-
|
|
41869
|
+
channel.writeLine(pc.dim(` ${cacheLine}`));
|
|
41127
41870
|
}
|
|
41128
41871
|
if (!result.text) {
|
|
41129
|
-
|
|
41872
|
+
channel.writeLine(pc.yellow(t("cli.no_output")));
|
|
41130
41873
|
}
|
|
41131
41874
|
return 0;
|
|
41132
41875
|
}
|
|
41133
|
-
|
|
41876
|
+
channel.writeLine(`${t("error.prefix")}${result.error}`, "stderr");
|
|
41134
41877
|
return 1;
|
|
41135
41878
|
}
|
|
41136
41879
|
|
|
41137
41880
|
// src/cli/main.ts
|
|
41138
41881
|
init_setup();
|
|
41882
|
+
|
|
41883
|
+
// src/cli/setup-order.ts
|
|
41884
|
+
var SECURITY_BASH_BLOCKLIST = [
|
|
41885
|
+
"rm",
|
|
41886
|
+
"dd",
|
|
41887
|
+
"chmod",
|
|
41888
|
+
"wget",
|
|
41889
|
+
"curl",
|
|
41890
|
+
"scp",
|
|
41891
|
+
"ssh",
|
|
41892
|
+
"nc",
|
|
41893
|
+
"netcat",
|
|
41894
|
+
"sudo",
|
|
41895
|
+
"su",
|
|
41896
|
+
"kill",
|
|
41897
|
+
"pkill",
|
|
41898
|
+
"killall",
|
|
41899
|
+
"shutdown",
|
|
41900
|
+
"reboot"
|
|
41901
|
+
];
|
|
41902
|
+
function applyAnswersToConfig(config, a) {
|
|
41903
|
+
config.provider = {
|
|
41904
|
+
...config.provider,
|
|
41905
|
+
type: a.provider,
|
|
41906
|
+
baseUrl: a.apiBase,
|
|
41907
|
+
apiKey: a.apiKey
|
|
41908
|
+
};
|
|
41909
|
+
config.model = a.model;
|
|
41910
|
+
config.contextWindow = a.contextWindow;
|
|
41911
|
+
config.maxToolIterations = a.maxToolIterations;
|
|
41912
|
+
config.locale = a.locale;
|
|
41913
|
+
if (config.security) {
|
|
41914
|
+
config.security.enabled = true;
|
|
41915
|
+
config.security.bash.enabled = true;
|
|
41916
|
+
config.security.bash.blockDangerousFlags = a.securityFlagsBlock || config.security.bash.blockDangerousFlags;
|
|
41917
|
+
if (a.securityBashBlock) {
|
|
41918
|
+
config.security.bash.blacklist = [
|
|
41919
|
+
...new Set([...config.security.bash.blacklist, ...SECURITY_BASH_BLOCKLIST])
|
|
41920
|
+
];
|
|
41921
|
+
}
|
|
41922
|
+
if (!a.securityPathsDeny)
|
|
41923
|
+
config.security.paths.denied = [];
|
|
41924
|
+
}
|
|
41925
|
+
return config;
|
|
41926
|
+
}
|
|
41927
|
+
|
|
41928
|
+
// src/cli/relaunch.ts
|
|
41929
|
+
init_output();
|
|
41930
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
41931
|
+
function relaunchArgs(argv) {
|
|
41932
|
+
return argv.slice(1);
|
|
41933
|
+
}
|
|
41934
|
+
function relaunchCli() {
|
|
41935
|
+
const args = relaunchArgs(process.argv);
|
|
41936
|
+
const entry = args[0];
|
|
41937
|
+
if (!entry)
|
|
41938
|
+
process.exit(0);
|
|
41939
|
+
const child = spawnSync4(process.execPath, args, {
|
|
41940
|
+
stdio: "inherit",
|
|
41941
|
+
env: { ...process.env, MMA_POST_SETUP: "1" }
|
|
41942
|
+
});
|
|
41943
|
+
if (child.error) {
|
|
41944
|
+
getDefaultChannel().writeLine(`Failed to relaunch the CLI: ${child.error.message}`, "stderr");
|
|
41945
|
+
process.exit(1);
|
|
41946
|
+
}
|
|
41947
|
+
process.exit(child.status ?? 0);
|
|
41948
|
+
}
|
|
41949
|
+
|
|
41950
|
+
// src/cli/main.ts
|
|
41951
|
+
init_output();
|
|
41952
|
+
|
|
41953
|
+
// src/cli/json-payload.ts
|
|
41954
|
+
function buildJsonResult(result, diagnostics) {
|
|
41955
|
+
return {
|
|
41956
|
+
success: result.success,
|
|
41957
|
+
text: result.text,
|
|
41958
|
+
error: result.error ?? null,
|
|
41959
|
+
iterationCount: result.iterationCount,
|
|
41960
|
+
contextUsed: result.contextUsed ?? null,
|
|
41961
|
+
contextLimit: result.contextLimit ?? null,
|
|
41962
|
+
promptTokens: result.promptTokens ?? null,
|
|
41963
|
+
completionTokens: result.completionTokens ?? null,
|
|
41964
|
+
totalTokens: result.totalTokens ?? null,
|
|
41965
|
+
totalCost: result.totalCost ?? null,
|
|
41966
|
+
costBreakdown: result.costBreakdown ?? [],
|
|
41967
|
+
cache: result.cache ?? null,
|
|
41968
|
+
diagnostics
|
|
41969
|
+
};
|
|
41970
|
+
}
|
|
41971
|
+
function buildJsonError(error, diagnostics = []) {
|
|
41972
|
+
return {
|
|
41973
|
+
success: false,
|
|
41974
|
+
text: "",
|
|
41975
|
+
error,
|
|
41976
|
+
iterationCount: 0,
|
|
41977
|
+
diagnostics
|
|
41978
|
+
};
|
|
41979
|
+
}
|
|
41980
|
+
|
|
41981
|
+
// src/cli/main.ts
|
|
41139
41982
|
init_config2();
|
|
41140
41983
|
init_i18n();
|
|
41141
41984
|
init_colors();
|
|
41142
41985
|
import { existsSync as existsSync61 } from "fs";
|
|
41143
|
-
import { join as join57, dirname as
|
|
41986
|
+
import { join as join57, dirname as dirname26 } from "path";
|
|
41144
41987
|
import { homedir as homedir20 } from "os";
|
|
41145
41988
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
41146
41989
|
|
|
@@ -41151,6 +41994,7 @@ init_checker();
|
|
|
41151
41994
|
init_checker();
|
|
41152
41995
|
init_i18n();
|
|
41153
41996
|
init_colors();
|
|
41997
|
+
init_output();
|
|
41154
41998
|
|
|
41155
41999
|
class UpdaterModule {
|
|
41156
42000
|
name = "updater";
|
|
@@ -41166,8 +42010,8 @@ class UpdaterModule {
|
|
|
41166
42010
|
this.updater = new Updater(currentVersion, packageName, installRunner);
|
|
41167
42011
|
this.logger = logger4 ?? {
|
|
41168
42012
|
info: () => {},
|
|
41169
|
-
warn: (m) =>
|
|
41170
|
-
error: (m) =>
|
|
42013
|
+
warn: (m) => defaultOutputBus.log("warn", "updater", m),
|
|
42014
|
+
error: (m) => defaultOutputBus.log("error", "updater", m)
|
|
41171
42015
|
};
|
|
41172
42016
|
}
|
|
41173
42017
|
setInstallEnabled(enabled2) {
|
|
@@ -41227,7 +42071,7 @@ class UpdaterModule {
|
|
|
41227
42071
|
if (install.success) {
|
|
41228
42072
|
const changelog = readChangelog("micro-models-agent");
|
|
41229
42073
|
const latestEntry = changelog ? extractLatestChangelog(changelog) : null;
|
|
41230
|
-
const changelogBlock = latestEntry ?
|
|
42074
|
+
const changelogBlock = latestEntry ? pc.cyan(`
|
|
41231
42075
|
${t("cli.changelog_title", { version: result.latest })}
|
|
41232
42076
|
`) + latestEntry : "";
|
|
41233
42077
|
this.logger.info(t("updater.installed", {
|
|
@@ -41260,7 +42104,7 @@ init_environment();
|
|
|
41260
42104
|
init_data_sanitizer();
|
|
41261
42105
|
init_i18n();
|
|
41262
42106
|
init_utils();
|
|
41263
|
-
import { appendFileSync as appendFileSync7, mkdirSync as
|
|
42107
|
+
import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync24 } from "fs";
|
|
41264
42108
|
import { join as join56 } from "path";
|
|
41265
42109
|
import { homedir as homedir19 } from "os";
|
|
41266
42110
|
var CRASH_LOG_DIR = join56(homedir19(), ".mma", "logs");
|
|
@@ -41278,7 +42122,7 @@ function formatCrashEntry(type2, err) {
|
|
|
41278
42122
|
}
|
|
41279
42123
|
function writeCrashEntry(dir, entry) {
|
|
41280
42124
|
try {
|
|
41281
|
-
|
|
42125
|
+
mkdirSync24(dir, { recursive: true });
|
|
41282
42126
|
appendFileSync7(join56(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
|
|
41283
42127
|
`, "utf-8");
|
|
41284
42128
|
} catch {}
|
|
@@ -41342,17 +42186,15 @@ function closestCommand(input, known, maxDistance = 2) {
|
|
|
41342
42186
|
|
|
41343
42187
|
// src/cli/main.ts
|
|
41344
42188
|
init_utils();
|
|
42189
|
+
var jsonMode = false;
|
|
41345
42190
|
function startAutoUpdate(config) {
|
|
41346
42191
|
if (isDevEntryPath(fileURLToPath6(import.meta.url)))
|
|
41347
42192
|
return;
|
|
41348
42193
|
try {
|
|
41349
42194
|
const module = new UpdaterModule(config.updater, readMmaVersion(), "micro-models-agent", {
|
|
41350
|
-
info: (m) =>
|
|
41351
|
-
|
|
41352
|
-
|
|
41353
|
-
`),
|
|
41354
|
-
error: (m) => process.stderr.write(pc2.red(m) + `
|
|
41355
|
-
`)
|
|
42195
|
+
info: (m) => defaultOutputBus.log("info", "updater", m),
|
|
42196
|
+
warn: (m) => defaultOutputBus.log("warn", "updater", m),
|
|
42197
|
+
error: (m) => defaultOutputBus.log("error", "updater", m)
|
|
41356
42198
|
});
|
|
41357
42199
|
module.start();
|
|
41358
42200
|
return module;
|
|
@@ -41362,6 +42204,7 @@ function startAutoUpdate(config) {
|
|
|
41362
42204
|
}
|
|
41363
42205
|
async function main() {
|
|
41364
42206
|
installCrashHandlers();
|
|
42207
|
+
getDefaultChannel();
|
|
41365
42208
|
const program2 = createProgram();
|
|
41366
42209
|
const valueOpts = new Set(["-d", "--dir", "--reasoning"]);
|
|
41367
42210
|
const argv = process.argv.slice(2);
|
|
@@ -41385,7 +42228,7 @@ async function main() {
|
|
|
41385
42228
|
const noAgentsMd = opts.noAgentsMd === true;
|
|
41386
42229
|
const projectDir = opts.dir;
|
|
41387
42230
|
const exitOnComplete = opts.exitOnComplete === true;
|
|
41388
|
-
const
|
|
42231
|
+
const jsonOpt = opts.json === true;
|
|
41389
42232
|
const reasoningLevel = opts.reasoning;
|
|
41390
42233
|
const isSubcommand = program2.args.length > 0 && cmdNames.has(program2.args[0]);
|
|
41391
42234
|
if (isSubcommand) {
|
|
@@ -41394,15 +42237,20 @@ async function main() {
|
|
|
41394
42237
|
if (program2.args.length > 0) {
|
|
41395
42238
|
const suggestion = closestCommand(program2.args[0], [...cmdNames]);
|
|
41396
42239
|
if (suggestion && suggestion !== program2.args[0]) {
|
|
41397
|
-
|
|
42240
|
+
getDefaultChannel().writeLine(pc.yellow(`${t("cli.unknown_command", { input: program2.args[0], suggestion })}`), "stderr");
|
|
41398
42241
|
process.exit(2);
|
|
41399
42242
|
}
|
|
41400
42243
|
}
|
|
41401
42244
|
if (program2.args.length > 0) {
|
|
42245
|
+
if (jsonOpt) {
|
|
42246
|
+
jsonMode = true;
|
|
42247
|
+
getDefaultChannel().setQuiet(true);
|
|
42248
|
+
}
|
|
42249
|
+
const jsonSink = jsonOpt ? new JsonOutputSink(defaultOutputBus) : undefined;
|
|
41402
42250
|
const prompt = program2.args.join(" ");
|
|
41403
42251
|
const { agent, config, baseDir, legacyDetected } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete, reasoningLevel);
|
|
41404
42252
|
if (legacyDetected) {
|
|
41405
|
-
|
|
42253
|
+
getDefaultChannel().writeLine(pc.yellow(` ${t("config.legacy_hint")}`), "stderr");
|
|
41406
42254
|
}
|
|
41407
42255
|
const updater = exitOnComplete ? undefined : startAutoUpdate(config);
|
|
41408
42256
|
if (jsonMode) {
|
|
@@ -41411,30 +42259,17 @@ async function main() {
|
|
|
41411
42259
|
result2 = await agent.run(prompt);
|
|
41412
42260
|
} catch (err) {
|
|
41413
42261
|
const message = errMsg(err);
|
|
41414
|
-
process.stdout.write(JSON.stringify({ success: false, text: "", error: message, iterationCount: 0 }, null, 2));
|
|
41415
|
-
process.stdout.write(`
|
|
41416
|
-
`);
|
|
41417
42262
|
agent.shutdown();
|
|
42263
|
+
const diagnostics2 = jsonSink?.diagnostics() ?? [];
|
|
42264
|
+
jsonSink?.dispose();
|
|
42265
|
+
writeMachineJson(buildJsonError(message, diagnostics2));
|
|
41418
42266
|
await updater?.waitForIdle(1e4);
|
|
41419
42267
|
process.exit(1);
|
|
41420
42268
|
}
|
|
41421
42269
|
agent.shutdown();
|
|
41422
|
-
|
|
41423
|
-
|
|
41424
|
-
|
|
41425
|
-
error: result2.error ?? null,
|
|
41426
|
-
iterationCount: result2.iterationCount,
|
|
41427
|
-
contextUsed: result2.contextUsed ?? null,
|
|
41428
|
-
contextLimit: result2.contextLimit ?? null,
|
|
41429
|
-
promptTokens: result2.promptTokens ?? null,
|
|
41430
|
-
completionTokens: result2.completionTokens ?? null,
|
|
41431
|
-
totalTokens: result2.totalTokens ?? null,
|
|
41432
|
-
totalCost: result2.totalCost ?? null,
|
|
41433
|
-
costBreakdown: result2.costBreakdown ?? [],
|
|
41434
|
-
cache: result2.cache ?? null
|
|
41435
|
-
}, null, 2));
|
|
41436
|
-
process.stdout.write(`
|
|
41437
|
-
`);
|
|
42270
|
+
const diagnostics = jsonSink?.diagnostics() ?? [];
|
|
42271
|
+
jsonSink?.dispose();
|
|
42272
|
+
writeMachineJson(buildJsonResult(result2, diagnostics));
|
|
41438
42273
|
await updater?.waitForIdle(1e4);
|
|
41439
42274
|
process.exit(result2.success ? 0 : 1);
|
|
41440
42275
|
}
|
|
@@ -41484,6 +42319,19 @@ async function main() {
|
|
|
41484
42319
|
hasAnyConfig = hasDomainFiles3(mmaDir);
|
|
41485
42320
|
} catch {}
|
|
41486
42321
|
}
|
|
42322
|
+
const projectConfigPath = projectDir ? join57(projectDir, ".mmrc") : join57(process.cwd(), ".mmrc");
|
|
42323
|
+
if (!hasAnyConfig && !exitOnComplete && process.env.MMA_POST_SETUP !== "1") {
|
|
42324
|
+
getDefaultChannel().writeLine(`
|
|
42325
|
+
` + t("cli.first_run") + `
|
|
42326
|
+
`);
|
|
42327
|
+
const answers = await runSetup();
|
|
42328
|
+
const { config: config2 } = loadConfig({ configDir: mmaDir, projectConfigPath });
|
|
42329
|
+
applyReasoningCliOverride(config2, reasoningLevel);
|
|
42330
|
+
applyAnswersToConfig(config2, answers);
|
|
42331
|
+
saveConfig(config2, legacyConfigPath, dirname26(legacyConfigPath));
|
|
42332
|
+
getDefaultChannel().writeLine(pc.dim(` ${t("cli.setup_saved_restart")}`));
|
|
42333
|
+
relaunchCli();
|
|
42334
|
+
}
|
|
41487
42335
|
const {
|
|
41488
42336
|
agent,
|
|
41489
42337
|
config,
|
|
@@ -41498,58 +42346,16 @@ async function main() {
|
|
|
41498
42346
|
contextProbe
|
|
41499
42347
|
} = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete, reasoningLevel);
|
|
41500
42348
|
const repl = new Repl(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger4, true, envReport, undefined, execModule, contextProbe);
|
|
41501
|
-
if (!hasAnyConfig && !exitOnComplete) {
|
|
41502
|
-
console.log(pc2.yellow(`
|
|
41503
|
-
` + t("cli.first_run") + `
|
|
41504
|
-
`));
|
|
41505
|
-
const answers = await runSetup(repl.rl);
|
|
41506
|
-
config.provider.type = answers.provider;
|
|
41507
|
-
config.provider.baseUrl = answers.apiBase;
|
|
41508
|
-
config.provider.apiKey = answers.apiKey;
|
|
41509
|
-
config.model = answers.model;
|
|
41510
|
-
config.contextWindow = answers.contextWindow;
|
|
41511
|
-
config.maxToolIterations = answers.maxToolIterations;
|
|
41512
|
-
config.locale = answers.locale;
|
|
41513
|
-
if (config.security) {
|
|
41514
|
-
config.security.enabled = true;
|
|
41515
|
-
config.security.bash.enabled = true;
|
|
41516
|
-
config.security.bash.blockDangerousFlags = answers.securityFlagsBlock || config.security.bash.blockDangerousFlags;
|
|
41517
|
-
if (answers.securityBashBlock) {
|
|
41518
|
-
config.security.bash.blacklist = [
|
|
41519
|
-
...new Set([
|
|
41520
|
-
...config.security.bash.blacklist,
|
|
41521
|
-
"rm",
|
|
41522
|
-
"dd",
|
|
41523
|
-
"chmod",
|
|
41524
|
-
"wget",
|
|
41525
|
-
"curl",
|
|
41526
|
-
"scp",
|
|
41527
|
-
"ssh",
|
|
41528
|
-
"nc",
|
|
41529
|
-
"netcat",
|
|
41530
|
-
"sudo",
|
|
41531
|
-
"su",
|
|
41532
|
-
"kill",
|
|
41533
|
-
"pkill",
|
|
41534
|
-
"killall",
|
|
41535
|
-
"shutdown",
|
|
41536
|
-
"reboot"
|
|
41537
|
-
])
|
|
41538
|
-
];
|
|
41539
|
-
}
|
|
41540
|
-
if (!answers.securityPathsDeny) {
|
|
41541
|
-
config.security.paths.denied = [];
|
|
41542
|
-
}
|
|
41543
|
-
}
|
|
41544
|
-
saveConfig(config, legacyConfigPath, dirname25(legacyConfigPath));
|
|
41545
|
-
await agent.reconfigure(config);
|
|
41546
|
-
}
|
|
41547
42349
|
startAutoUpdate(config);
|
|
41548
42350
|
await repl.start();
|
|
41549
42351
|
}
|
|
41550
42352
|
}
|
|
41551
42353
|
main().catch((err) => {
|
|
41552
|
-
|
|
42354
|
+
if (jsonMode) {
|
|
42355
|
+
writeMachineJson(buildJsonError(errMsg(err)));
|
|
42356
|
+
} else {
|
|
42357
|
+
getDefaultChannel().writeLine(err instanceof Error ? err.stack ?? err.message : String(err), "stderr");
|
|
42358
|
+
}
|
|
41553
42359
|
process.exit(1);
|
|
41554
42360
|
});
|
|
41555
42361
|
export {
|