micro-models-agent 1.7.0 → 2.0.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 +33 -0
- package/dist/i18n/en.json +103 -10
- package/dist/i18n/ru.json +103 -10
- package/dist/main.js +1426 -259
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2804,6 +2804,10 @@ Fix the error and re-edit the file (a clean write clears the failure), or mark t
|
|
|
2804
2804
|
"cli.list_sessions": "List all sessions",
|
|
2805
2805
|
"cli.show_details": "Show session details",
|
|
2806
2806
|
"cli.delete_session": "Delete a session",
|
|
2807
|
+
"cli.export_session": "Export a session to a file (md, json, or jsonl)",
|
|
2808
|
+
"cli.export_format": "Output format: md|json|jsonl (default md)",
|
|
2809
|
+
"cli.export_out": "Output path ('-' for stdout)",
|
|
2810
|
+
"cli.export_no_redact": "Do not redact secrets",
|
|
2807
2811
|
"cli.first_run": "First run detected. Running setup wizard...",
|
|
2808
2812
|
"cli.first_run_oneshot": "No configuration found — running with defaults. Run `mma` (no arguments) once to set up the wizard.",
|
|
2809
2813
|
"cli.setup_saved_restart": "Settings saved. Restarting with the new configuration...",
|
|
@@ -2872,20 +2876,21 @@ Available commands:`,
|
|
|
2872
2876
|
"repl.exit_usage": "Usage: /exit",
|
|
2873
2877
|
"repl.clear": "Clear the screen",
|
|
2874
2878
|
"repl.clear_usage": "Usage: /clear",
|
|
2879
|
+
"repl.clear_hint": "Screen cleared. To start a fresh session and context: /new",
|
|
2875
2880
|
"repl.run": "Run a prompt through the agent",
|
|
2876
2881
|
"repl.run_usage": "Usage: /run <prompt>",
|
|
2877
|
-
"repl.config": "Show
|
|
2878
|
-
"repl.config_usage": "Usage: /config",
|
|
2879
|
-
"repl.reasoning": "
|
|
2880
|
-
"repl.reasoning_usage": "Usage: /reasoning [auto|none|low|medium|high|max]",
|
|
2882
|
+
"repl.config": "Show or change settings (get / set / reset)",
|
|
2883
|
+
"repl.config_usage": "Usage: /config [<key> [value]] | /config reset <key> | /config reset --all [--yes] | /config migrate",
|
|
2884
|
+
"repl.reasoning": "Show reasoning status, toggle display, or set effort level",
|
|
2885
|
+
"repl.reasoning_usage": "Usage: /reasoning [show|hide|level <auto|default|none|low|medium|high|max>]",
|
|
2881
2886
|
"repl.reasoning_level_set": "Reasoning level set to: {level}",
|
|
2882
2887
|
"repl.reasoning_invalid_level": "Invalid level '{level}'. Valid: {valid}",
|
|
2883
|
-
"repl.verbose": "Chat verbosity
|
|
2888
|
+
"repl.verbose": "Chat verbosity (quiet, normal, verbose)",
|
|
2884
2889
|
"repl.verbose_usage": "Usage: /verbose [quiet|normal|verbose]",
|
|
2885
2890
|
"repl.verbose_set": "Chat verbosity: {level}",
|
|
2886
2891
|
"repl.verbose_invalid_level": "Invalid level '{level}'. Valid: {valid}",
|
|
2887
2892
|
"repl.last_action_none": "No recent action to show.",
|
|
2888
|
-
"repl.status": "Show
|
|
2893
|
+
"repl.status": "Show a compact status line",
|
|
2889
2894
|
"repl.status_usage": "Usage: /status",
|
|
2890
2895
|
"repl.plugins": "List loaded plugins",
|
|
2891
2896
|
"repl.plugins_usage": "Usage: /plugins [--all]",
|
|
@@ -2925,11 +2930,13 @@ Available commands:`,
|
|
|
2925
2930
|
"repl.context": "Context:",
|
|
2926
2931
|
"repl.sysprompt_label": "System prompt:",
|
|
2927
2932
|
"repl.sysprompt_size": "{used} / {budget} tokens",
|
|
2928
|
-
"repl.sysprompt_desc": "
|
|
2933
|
+
"repl.sysprompt_desc": "System prompt size and blocks (use --full for the text)",
|
|
2934
|
+
"repl.sysprompt_usage": "Usage: /sysprompt [--full]",
|
|
2935
|
+
"repl.sysprompt_full_hint": "Full prompt text hidden — run /sysprompt --full to print it.",
|
|
2929
2936
|
"repl.sysprompt_tokens": "System prompt ({count} tokens):",
|
|
2930
2937
|
"repl.excluded_blocks": `
|
|
2931
2938
|
Excluded blocks: {count}`,
|
|
2932
|
-
"repl.context_usage": "Usage: /context [<size> | system <
|
|
2939
|
+
"repl.context_usage": "Usage: /context [<size, min 1024> | system <share> | reserve <share>] (share 0.05–0.9 or e.g. 10%; system+reserve ≤ 0.95)",
|
|
2933
2940
|
"repl.msgs": "msgs",
|
|
2934
2941
|
"repl.max_iters": "Max iters:",
|
|
2935
2942
|
"repl.stuck_thresh": "Stuck thresh:",
|
|
@@ -2973,13 +2980,105 @@ Excluded blocks: {count}`,
|
|
|
2973
2980
|
"repl.provider_list": "List configured providers or hot-swap the active one",
|
|
2974
2981
|
"repl.provider_current": "Current provider",
|
|
2975
2982
|
"repl.provider_set": "Provider set to: {name}",
|
|
2976
|
-
"repl.provider_usage":
|
|
2983
|
+
"repl.provider_usage": `Usage: /provider list | /provider use <name> | /provider add <name> [flags]
|
|
2984
|
+
--url <url> base API URL (fallback: known presets)
|
|
2985
|
+
--key <key> API key
|
|
2986
|
+
--priority <n> fallback order; lower = tried first
|
|
2987
|
+
--context-window <n> per-provider context window (tokens)
|
|
2988
|
+
--rpm <n> max requests/minute (default 60)
|
|
2989
|
+
--parallel <n> max parallel tasks (default 1)`,
|
|
2977
2990
|
"repl.provider_add_missing_value": "Missing value for {flag}",
|
|
2991
|
+
"repl.provider_add_invalid_number": "Invalid number for {flag}: '{value}'",
|
|
2978
2992
|
"repl.provider_switch_hint": "Switch to it with: /provider use {name}",
|
|
2993
|
+
"repl.provider_flag_url": "Base API URL (fallback: known presets)",
|
|
2994
|
+
"repl.provider_flag_key": "API key",
|
|
2995
|
+
"repl.provider_flag_priority": "Fallback order; lower = tried first",
|
|
2996
|
+
"repl.provider_flag_context_window": "Per-provider context window (tokens)",
|
|
2997
|
+
"repl.provider_flag_rpm": "Max requests per minute (default 60)",
|
|
2998
|
+
"repl.provider_flag_parallel": "Max parallel tasks (default 1)",
|
|
2979
2999
|
"repl.model_list": "List models of the active provider or switch the model",
|
|
2980
3000
|
"repl.model_current": "Current model",
|
|
2981
3001
|
"repl.model_set": "Model set to: {name}",
|
|
2982
|
-
"repl.model_usage": "/model list
|
|
3002
|
+
"repl.model_usage": "Usage: /model list | /model use <name>",
|
|
3003
|
+
"repl.unknown_sub": "Unknown subcommand '{sub}' for /{cmd}. See usage below.",
|
|
3004
|
+
"repl.help_unknown": "Unknown command '/{name}'",
|
|
3005
|
+
"repl.help_aliases": "Aliases: {names}",
|
|
3006
|
+
"repl.help_examples": "Examples:",
|
|
3007
|
+
"repl.export": "Export a session to a file",
|
|
3008
|
+
"repl.export_usage": "Usage: /export [<id|name>] [--format md|json|jsonl] [--out <path>] [--no-redact]",
|
|
3009
|
+
"config.header": "Managed settings",
|
|
3010
|
+
"config.col_setting": "Setting",
|
|
3011
|
+
"config.col_value": "Value",
|
|
3012
|
+
"config.col_domain": "Domain",
|
|
3013
|
+
"config.col_change": "Change with",
|
|
3014
|
+
"config.session_line": "Session: {name} ({id}) — {count} messages",
|
|
3015
|
+
"config.usage_hint": "Get: /config <key> · Set: /config <key> <value> · Reset: /config reset <key>",
|
|
3016
|
+
"config.saved": "saved · reset: /config reset {key}",
|
|
3017
|
+
"config.read_only_hint": "read-only",
|
|
3018
|
+
"config.read_only": "'{key}' is read-only",
|
|
3019
|
+
"config.unknown_key": "Unknown key '{key}'. {suggestion}",
|
|
3020
|
+
"config.suggest": "Did you mean '{name}'?",
|
|
3021
|
+
"config.valid_keys": "Valid keys: {keys}",
|
|
3022
|
+
"config.invalid_value": "Invalid value for {key}. {hint}",
|
|
3023
|
+
"config.range": "Value out of range for {key}",
|
|
3024
|
+
"config.combined": "system + reserve must stay below 0.95",
|
|
3025
|
+
"config.hint_string": "Expected a non-empty string",
|
|
3026
|
+
"config.hint_enum": "Allowed: {values}",
|
|
3027
|
+
"config.hint_bool": "Expected on/off",
|
|
3028
|
+
"config.hint_share": "Expected 0.05–0.9 or a percentage (e.g. 10%)",
|
|
3029
|
+
"config.hint_int": "Expected an integer ≥ {min}",
|
|
3030
|
+
"config.reset_ok": "{key} restored to session-start value: {value} · saved",
|
|
3031
|
+
"config.reset_unchanged": "{key} already at session value",
|
|
3032
|
+
"config.reset_none": "No settings changed this session",
|
|
3033
|
+
"config.reset_all_confirm": "Reset {count} changed setting(s) to session-start values? [y/N] ",
|
|
3034
|
+
"config.reset_all_done": "Restored {count} setting(s) · saved",
|
|
3035
|
+
"config.reset_all_needs_yes": "Refusing to reset without confirmation in non-interactive mode; pass --yes",
|
|
3036
|
+
"config.reset_cancelled": "Reset cancelled",
|
|
3037
|
+
"config.reset_usage": "Usage: /config reset <key> | /config reset --all [--yes]",
|
|
3038
|
+
"config.alias_label": "alias of",
|
|
3039
|
+
"config.group_label": "group",
|
|
3040
|
+
"reasoning.status": "Reasoning: display {display} · effort {level} {auto}",
|
|
3041
|
+
"reasoning.on": "on",
|
|
3042
|
+
"reasoning.off": "off",
|
|
3043
|
+
"reasoning.auto_on": "(auto policy)",
|
|
3044
|
+
"reasoning.auto_off": "(auto policy off)",
|
|
3045
|
+
"reasoning.auto_off_hint": "Auto policy off. Restore with: /config reset reasoning.mode",
|
|
3046
|
+
"reasoning.display_set": "Reasoning display: {state}",
|
|
3047
|
+
"reasoning.unknown_sub": "Unknown argument '{sub}'.",
|
|
3048
|
+
"reasoning.sub_show": "Show reasoning content",
|
|
3049
|
+
"reasoning.sub_hide": "Hide reasoning content",
|
|
3050
|
+
"reasoning.sub_level": "Set reasoning effort level",
|
|
3051
|
+
"verbose.status": "Verbosity: {level}",
|
|
3052
|
+
"verbose.sub_quiet": "One line per action",
|
|
3053
|
+
"verbose.sub_normal": "Add short result summaries",
|
|
3054
|
+
"verbose.sub_verbose": "Full per-action detail",
|
|
3055
|
+
"context.unknown_arg": "Unknown argument '{arg}'.",
|
|
3056
|
+
"context.sub_system": "System-prompt share",
|
|
3057
|
+
"context.sub_reserve": "Response-reserve share",
|
|
3058
|
+
"model.not_in_list": "Note: '{name}' is not in the known model list",
|
|
3059
|
+
"model.sub_list": "List models of the active provider",
|
|
3060
|
+
"model.sub_use": "Switch model",
|
|
3061
|
+
"provider.sub_list": "List configured providers",
|
|
3062
|
+
"provider.sub_use": "Switch active provider",
|
|
3063
|
+
"provider.sub_add": "Add a provider",
|
|
3064
|
+
"map.sub_summary": "Show the project map summary",
|
|
3065
|
+
"map.sub_refresh": "Rebuild the project index",
|
|
3066
|
+
"map.sub_find": "Search the project map",
|
|
3067
|
+
"lsp.sub_status": "Show LSP server status",
|
|
3068
|
+
"lsp.sub_restart": "Reset disabled servers",
|
|
3069
|
+
"lsp.sub_check": "Run an LSP check on a path",
|
|
3070
|
+
"skill.sub_list": "List available skills",
|
|
3071
|
+
"skill.sub_loaded": "List loaded skills",
|
|
3072
|
+
"skill.sub_load": "Load a skill",
|
|
3073
|
+
"skill.sub_unload": "Unload a skill",
|
|
3074
|
+
"skill.sub_search": "Search skills",
|
|
3075
|
+
"export.written": "Exported to {path}",
|
|
3076
|
+
"export.redacted": "secrets redacted (--no-redact to disable)",
|
|
3077
|
+
"export.raw": "secrets NOT redacted",
|
|
3078
|
+
"export.empty": "session has no messages — nothing exported",
|
|
3079
|
+
"export.invalid_format": "Unknown format '{format}'. Use md|json|jsonl",
|
|
3080
|
+
"export.missing_value": "Missing value for {flag}",
|
|
3081
|
+
"export.write_failed": "Failed to write export: {error}",
|
|
2983
3082
|
"repl.group.general": "General",
|
|
2984
3083
|
"repl.group.agent": "Agent",
|
|
2985
3084
|
"repl.group.session": "Sessions",
|
|
@@ -3677,6 +3776,10 @@ var init_ru = __esm(() => {
|
|
|
3677
3776
|
"cli.list_sessions": "Список всех сессий",
|
|
3678
3777
|
"cli.show_details": "Показать детали сессии",
|
|
3679
3778
|
"cli.delete_session": "Удалить сессию",
|
|
3779
|
+
"cli.export_session": "Экспортировать сессию в файл (md, json или jsonl)",
|
|
3780
|
+
"cli.export_format": "Формат вывода: md|json|jsonl (по умолчанию md)",
|
|
3781
|
+
"cli.export_out": "Путь вывода ('-' для stdout)",
|
|
3782
|
+
"cli.export_no_redact": "Не скрывать секреты",
|
|
3680
3783
|
"cli.first_run": "Первый запуск. Запускаем мастер настройки...",
|
|
3681
3784
|
"cli.first_run_oneshot": "Конфигурация не найдена — запуск с настройками по умолчанию. Запустите `mma` без аргументов один раз для настройки.",
|
|
3682
3785
|
"cli.setup_saved_restart": "Настройки сохранены. Перезапуск с новой конфигурацией...",
|
|
@@ -3745,20 +3848,21 @@ var init_ru = __esm(() => {
|
|
|
3745
3848
|
"repl.exit_usage": "Использование: /exit",
|
|
3746
3849
|
"repl.clear": "Очистить экран",
|
|
3747
3850
|
"repl.clear_usage": "Использование: /clear",
|
|
3851
|
+
"repl.clear_hint": "Экран очищен. Новая сессия и контекст: /new",
|
|
3748
3852
|
"repl.run": "Выполнить запрос через агента",
|
|
3749
3853
|
"repl.run_usage": "Использование: /run <запрос>",
|
|
3750
|
-
"repl.config": "Показать
|
|
3751
|
-
"repl.config_usage": "Использование: /config",
|
|
3752
|
-
"repl.reasoning": "
|
|
3753
|
-
"repl.reasoning_usage": "Использование: /reasoning [auto|none|low|medium|high|max]",
|
|
3854
|
+
"repl.config": "Показать или изменить настройки (get / set / reset)",
|
|
3855
|
+
"repl.config_usage": "Использование: /config [<ключ> [значение]] | /config reset <ключ> | /config reset --all [--yes] | /config migrate",
|
|
3856
|
+
"repl.reasoning": "Показать статус рассуждений, переключить показ или уровень",
|
|
3857
|
+
"repl.reasoning_usage": "Использование: /reasoning [show|hide|level <auto|default|none|low|medium|high|max>]",
|
|
3754
3858
|
"repl.reasoning_level_set": "Уровень рассуждений установлен: {level}",
|
|
3755
3859
|
"repl.reasoning_invalid_level": "Неверный уровень '{level}'. Допустимые: {valid}",
|
|
3756
|
-
"repl.verbose": "Подробность
|
|
3860
|
+
"repl.verbose": "Подробность вывода (quiet, normal, verbose)",
|
|
3757
3861
|
"repl.verbose_usage": "Использование: /verbose [quiet|normal|verbose]",
|
|
3758
3862
|
"repl.verbose_set": "Подробность вывода: {level}",
|
|
3759
3863
|
"repl.verbose_invalid_level": "Неверный уровень '{level}'. Допустимые: {valid}",
|
|
3760
3864
|
"repl.last_action_none": "Нет недавнего действия для показа.",
|
|
3761
|
-
"repl.status": "Показать
|
|
3865
|
+
"repl.status": "Показать компактную строку статуса",
|
|
3762
3866
|
"repl.status_usage": "Использование: /status",
|
|
3763
3867
|
"repl.plugins": "Список загруженных плагинов",
|
|
3764
3868
|
"repl.plugins_usage": "Использование: /plugins [--all]",
|
|
@@ -3798,11 +3902,13 @@ var init_ru = __esm(() => {
|
|
|
3798
3902
|
"repl.context": "Контекст:",
|
|
3799
3903
|
"repl.sysprompt_label": "Системный промпт:",
|
|
3800
3904
|
"repl.sysprompt_size": "{used} / {budget} токенов",
|
|
3801
|
-
"repl.sysprompt_desc": "
|
|
3905
|
+
"repl.sysprompt_desc": "Размер системного промпта и блоки (текст — через --full)",
|
|
3906
|
+
"repl.sysprompt_usage": "Использование: /sysprompt [--full]",
|
|
3907
|
+
"repl.sysprompt_full_hint": "Полный текст промпта скрыт — выполните /sysprompt --full.",
|
|
3802
3908
|
"repl.sysprompt_tokens": "Системный промпт ({count} токенов):",
|
|
3803
3909
|
"repl.excluded_blocks": `
|
|
3804
3910
|
Исключённые блоки: {count}`,
|
|
3805
|
-
"repl.context_usage": "Использование: /context [
|
|
3911
|
+
"repl.context_usage": "Использование: /context [<размер, мин 1024> | system <доля> | reserve <доля>] (доля 0.05–0.9 или напр. 10%; system+reserve ≤ 0.95)",
|
|
3806
3912
|
"repl.msgs": "сообщ.",
|
|
3807
3913
|
"repl.max_iters": "Макс итераций:",
|
|
3808
3914
|
"repl.stuck_thresh": "Порог зависания:",
|
|
@@ -3846,13 +3952,105 @@ var init_ru = __esm(() => {
|
|
|
3846
3952
|
"repl.provider_list": "Список настроенных провайдеров или горячая смена активного",
|
|
3847
3953
|
"repl.provider_current": "Текущий провайдер",
|
|
3848
3954
|
"repl.provider_set": "Провайдер установлен: {name}",
|
|
3849
|
-
"repl.provider_usage":
|
|
3955
|
+
"repl.provider_usage": `Использование: /provider list | /provider use <имя> | /provider add <имя> [флаги]
|
|
3956
|
+
--url <url> базовый URL API (иначе — из пресетов)
|
|
3957
|
+
--key <ключ> API-ключ
|
|
3958
|
+
--priority <n> порядок fallback; меньше = раньше
|
|
3959
|
+
--context-window <n> окно контекста провайдера (токены)
|
|
3960
|
+
--rpm <n> запросов/мин (по умолчанию 60)
|
|
3961
|
+
--parallel <n> параллельных задач (по умолчанию 1)`,
|
|
3850
3962
|
"repl.provider_add_missing_value": "Нет значения для {flag}",
|
|
3963
|
+
"repl.provider_add_invalid_number": "Неверное число для {flag}: '{value}'",
|
|
3851
3964
|
"repl.provider_switch_hint": "Переключитесь на него: /provider use {name}",
|
|
3965
|
+
"repl.provider_flag_url": "Базовый URL API (иначе — из пресетов)",
|
|
3966
|
+
"repl.provider_flag_key": "API-ключ",
|
|
3967
|
+
"repl.provider_flag_priority": "Порядок fallback; меньше = раньше",
|
|
3968
|
+
"repl.provider_flag_context_window": "Окно контекста провайдера (токены)",
|
|
3969
|
+
"repl.provider_flag_rpm": "Запросов в минуту (по умолчанию 60)",
|
|
3970
|
+
"repl.provider_flag_parallel": "Параллельных задач (по умолчанию 1)",
|
|
3852
3971
|
"repl.model_list": "Список моделей активного провайдера или смена модели",
|
|
3853
3972
|
"repl.model_current": "Текущая модель",
|
|
3854
3973
|
"repl.model_set": "Модель установлена: {name}",
|
|
3855
|
-
"repl.model_usage": "/model list
|
|
3974
|
+
"repl.model_usage": "Использование: /model list | /model use <имя>",
|
|
3975
|
+
"repl.unknown_sub": "Неизвестная подкоманда '{sub}' для /{cmd}. См. использование ниже.",
|
|
3976
|
+
"repl.help_unknown": "Неизвестная команда '/{name}'",
|
|
3977
|
+
"repl.help_aliases": "Алиасы: {names}",
|
|
3978
|
+
"repl.help_examples": "Примеры:",
|
|
3979
|
+
"repl.export": "Экспортировать сессию в файл",
|
|
3980
|
+
"repl.export_usage": "Использование: /export [<id|имя>] [--format md|json|jsonl] [--out <путь>] [--no-redact]",
|
|
3981
|
+
"config.header": "Управляемые настройки",
|
|
3982
|
+
"config.col_setting": "Настройка",
|
|
3983
|
+
"config.col_value": "Значение",
|
|
3984
|
+
"config.col_domain": "Домен",
|
|
3985
|
+
"config.col_change": "Как менять",
|
|
3986
|
+
"config.session_line": "Сессия: {name} ({id}) — {count} сообщений",
|
|
3987
|
+
"config.usage_hint": "Чтение: /config <ключ> · Запись: /config <ключ> <значение> · Сброс: /config reset <ключ>",
|
|
3988
|
+
"config.saved": "сохранено · сброс: /config reset {key}",
|
|
3989
|
+
"config.read_only_hint": "только чтение",
|
|
3990
|
+
"config.read_only": "'{key}' — только чтение",
|
|
3991
|
+
"config.unknown_key": "Неизвестный ключ '{key}'. {suggestion}",
|
|
3992
|
+
"config.suggest": "Возможно, вы имели в виду '{name}'?",
|
|
3993
|
+
"config.valid_keys": "Допустимые ключи: {keys}",
|
|
3994
|
+
"config.invalid_value": "Неверное значение для {key}. {hint}",
|
|
3995
|
+
"config.range": "Значение вне диапазона для {key}",
|
|
3996
|
+
"config.combined": "system + reserve должны оставаться ниже 0.95",
|
|
3997
|
+
"config.hint_string": "Ожидается непустая строка",
|
|
3998
|
+
"config.hint_enum": "Допустимые: {values}",
|
|
3999
|
+
"config.hint_bool": "Ожидается on/off",
|
|
4000
|
+
"config.hint_share": "Ожидается 0.05–0.9 или процент (напр. 10%)",
|
|
4001
|
+
"config.hint_int": "Ожидается целое ≥ {min}",
|
|
4002
|
+
"config.reset_ok": "{key} восстановлен к значению на старте сессии: {value} · сохранено",
|
|
4003
|
+
"config.reset_unchanged": "{key} уже соответствует значению сессии",
|
|
4004
|
+
"config.reset_none": "В этой сессии настройки не менялись",
|
|
4005
|
+
"config.reset_all_confirm": "Сбросить {count} изменённых настроек к значениям на старте сессии? [y/N] ",
|
|
4006
|
+
"config.reset_all_done": "Восстановлено настроек: {count} · сохранено",
|
|
4007
|
+
"config.reset_all_needs_yes": "Отказ от сброса без подтверждения в неинтерактивном режиме; укажите --yes",
|
|
4008
|
+
"config.reset_cancelled": "Сброс отменён",
|
|
4009
|
+
"config.reset_usage": "Использование: /config reset <ключ> | /config reset --all [--yes]",
|
|
4010
|
+
"config.alias_label": "алиас",
|
|
4011
|
+
"config.group_label": "группа",
|
|
4012
|
+
"reasoning.status": "Рассуждения: показ {display} · усилие {level} {auto}",
|
|
4013
|
+
"reasoning.on": "вкл",
|
|
4014
|
+
"reasoning.off": "выкл",
|
|
4015
|
+
"reasoning.auto_on": "(авто-политика)",
|
|
4016
|
+
"reasoning.auto_off": "(авто-политика выключена)",
|
|
4017
|
+
"reasoning.auto_off_hint": "Авто-политика выключена. Вернуть: /config reset reasoning.mode",
|
|
4018
|
+
"reasoning.display_set": "Показ рассуждений: {state}",
|
|
4019
|
+
"reasoning.unknown_sub": "Неизвестный аргумент '{sub}'.",
|
|
4020
|
+
"reasoning.sub_show": "Показывать рассуждения",
|
|
4021
|
+
"reasoning.sub_hide": "Скрыть рассуждения",
|
|
4022
|
+
"reasoning.sub_level": "Установить уровень рассуждений",
|
|
4023
|
+
"verbose.status": "Подробность: {level}",
|
|
4024
|
+
"verbose.sub_quiet": "Одна строка на действие",
|
|
4025
|
+
"verbose.sub_normal": "Плюс короткие сводки результатов",
|
|
4026
|
+
"verbose.sub_verbose": "Полная деталь по действиям",
|
|
4027
|
+
"context.unknown_arg": "Неизвестный аргумент '{arg}'.",
|
|
4028
|
+
"context.sub_system": "Доля системного промпта",
|
|
4029
|
+
"context.sub_reserve": "Доля резерва ответа",
|
|
4030
|
+
"model.not_in_list": "Примечание: '{name}' нет в списке известных моделей",
|
|
4031
|
+
"model.sub_list": "Список моделей активного провайдера",
|
|
4032
|
+
"model.sub_use": "Сменить модель",
|
|
4033
|
+
"provider.sub_list": "Список настроенных провайдеров",
|
|
4034
|
+
"provider.sub_use": "Сменить активного провайдера",
|
|
4035
|
+
"provider.sub_add": "Добавить провайдера",
|
|
4036
|
+
"map.sub_summary": "Показать сводку карты проекта",
|
|
4037
|
+
"map.sub_refresh": "Перестроить индекс проекта",
|
|
4038
|
+
"map.sub_find": "Поиск по карте проекта",
|
|
4039
|
+
"lsp.sub_status": "Статус LSP-серверов",
|
|
4040
|
+
"lsp.sub_restart": "Сбросить отключённые серверы",
|
|
4041
|
+
"lsp.sub_check": "Запустить LSP-проверку пути",
|
|
4042
|
+
"skill.sub_list": "Список доступных скиллов",
|
|
4043
|
+
"skill.sub_loaded": "Список загруженных скиллов",
|
|
4044
|
+
"skill.sub_load": "Загрузить скилл",
|
|
4045
|
+
"skill.sub_unload": "Выгрузить скилл",
|
|
4046
|
+
"skill.sub_search": "Поиск скиллов",
|
|
4047
|
+
"export.written": "Экспортировано в {path}",
|
|
4048
|
+
"export.redacted": "секреты скрыты (--no-redact чтобы отключить)",
|
|
4049
|
+
"export.raw": "секреты НЕ скрыты",
|
|
4050
|
+
"export.empty": "в сессии нет сообщений — экспорт не создан",
|
|
4051
|
+
"export.invalid_format": "Неизвестный формат '{format}'. Используйте md|json|jsonl",
|
|
4052
|
+
"export.missing_value": "Нет значения для {flag}",
|
|
4053
|
+
"export.write_failed": "Не удалось записать экспорт: {error}",
|
|
3856
4054
|
"repl.reload": "Перезагрузить агента с текущим конфигом",
|
|
3857
4055
|
"repl.reload_usage": "Использование: /reload",
|
|
3858
4056
|
"repl.reloading": "Перезагрузка агента...",
|
|
@@ -6606,7 +6804,7 @@ class OpenAICompatProvider {
|
|
|
6606
6804
|
}
|
|
6607
6805
|
}
|
|
6608
6806
|
async* streamOnce(messages, tools, signal, options, onEmit, idleTimeoutMs) {
|
|
6609
|
-
const maxTokens = options?.maxTokens ?? this.config.maxCompletionTokens ??
|
|
6807
|
+
const maxTokens = options?.maxTokens ?? this.config.maxCompletionTokens ?? DEFAULT_MAX_COMPLETION_TOKENS;
|
|
6610
6808
|
const body = buildRequestBody({
|
|
6611
6809
|
model: this.model,
|
|
6612
6810
|
messages,
|
|
@@ -6872,7 +7070,7 @@ class OpenAICompatProvider {
|
|
|
6872
7070
|
};
|
|
6873
7071
|
}
|
|
6874
7072
|
async doNonStreaming(messages, tools, signal, options) {
|
|
6875
|
-
const maxTokens = options?.maxTokens ?? this.config.maxCompletionTokens ??
|
|
7073
|
+
const maxTokens = options?.maxTokens ?? this.config.maxCompletionTokens ?? DEFAULT_MAX_COMPLETION_TOKENS;
|
|
6876
7074
|
const body = buildRequestBody({
|
|
6877
7075
|
model: this.model,
|
|
6878
7076
|
messages,
|
|
@@ -7048,7 +7246,7 @@ class OpenAICompatProvider {
|
|
|
7048
7246
|
});
|
|
7049
7247
|
}
|
|
7050
7248
|
}
|
|
7051
|
-
var REQUEST_TIMEOUT_MS = 120000, MAX_RATE_WAIT_MS = 30000, cachedUserAgent = null;
|
|
7249
|
+
var REQUEST_TIMEOUT_MS = 120000, MAX_RATE_WAIT_MS = 30000, DEFAULT_MAX_COMPLETION_TOKENS = 8192, cachedUserAgent = null;
|
|
7052
7250
|
var init_openai_compat = __esm(() => {
|
|
7053
7251
|
init_token_counter();
|
|
7054
7252
|
init_i18n();
|
|
@@ -24564,7 +24762,7 @@ import {
|
|
|
24564
24762
|
appendFileSync as appendFileSync6
|
|
24565
24763
|
} from "fs";
|
|
24566
24764
|
import { join as join34 } from "path";
|
|
24567
|
-
import { gzipSync } from "zlib";
|
|
24765
|
+
import { gzipSync, gunzipSync } from "zlib";
|
|
24568
24766
|
|
|
24569
24767
|
class SessionStore {
|
|
24570
24768
|
baseDir;
|
|
@@ -24700,6 +24898,24 @@ class SessionStore {
|
|
|
24700
24898
|
return [];
|
|
24701
24899
|
}
|
|
24702
24900
|
}
|
|
24901
|
+
loadRotatedHistory(id) {
|
|
24902
|
+
const gzPath = join34(this.baseDir, `${id}.jsonl.gz`);
|
|
24903
|
+
if (!existsSync41(gzPath))
|
|
24904
|
+
return [];
|
|
24905
|
+
try {
|
|
24906
|
+
const content = gunzipSync(readFileSync25(gzPath)).toString("utf-8");
|
|
24907
|
+
return content.split(`
|
|
24908
|
+
`).filter(Boolean).map((line) => {
|
|
24909
|
+
try {
|
|
24910
|
+
return JSON.parse(line);
|
|
24911
|
+
} catch {
|
|
24912
|
+
return null;
|
|
24913
|
+
}
|
|
24914
|
+
}).filter((m) => m !== null);
|
|
24915
|
+
} catch {
|
|
24916
|
+
return [];
|
|
24917
|
+
}
|
|
24918
|
+
}
|
|
24703
24919
|
appendSessionLog(id, entry) {
|
|
24704
24920
|
const dir = this.sessionDir(id);
|
|
24705
24921
|
mkdirSync18(dir, { recursive: true, mode: 448 });
|
|
@@ -24896,6 +25112,12 @@ class SessionManager {
|
|
|
24896
25112
|
return [];
|
|
24897
25113
|
return this.store.loadHistory(this.activeId);
|
|
24898
25114
|
}
|
|
25115
|
+
getHistory(id) {
|
|
25116
|
+
const live = this.store.loadHistory(id);
|
|
25117
|
+
if (live.length > 0)
|
|
25118
|
+
return live;
|
|
25119
|
+
return this.store.loadRotatedHistory(id);
|
|
25120
|
+
}
|
|
24899
25121
|
getSessionContext() {
|
|
24900
25122
|
if (!this.activeId)
|
|
24901
25123
|
return;
|
|
@@ -29761,6 +29983,87 @@ var init_setup_order = __esm(() => {
|
|
|
29761
29983
|
];
|
|
29762
29984
|
});
|
|
29763
29985
|
|
|
29986
|
+
// src/modules/session/export.ts
|
|
29987
|
+
function roleHeading(role) {
|
|
29988
|
+
switch (role) {
|
|
29989
|
+
case "user":
|
|
29990
|
+
return "User";
|
|
29991
|
+
case "assistant":
|
|
29992
|
+
return "Assistant";
|
|
29993
|
+
case "tool":
|
|
29994
|
+
return "Tool";
|
|
29995
|
+
case "system":
|
|
29996
|
+
return "System";
|
|
29997
|
+
default:
|
|
29998
|
+
return role;
|
|
29999
|
+
}
|
|
30000
|
+
}
|
|
30001
|
+
function renderSessionMarkdown(meta, messages) {
|
|
30002
|
+
const lines = [];
|
|
30003
|
+
const name = meta?.name ?? "session";
|
|
30004
|
+
const id = meta?.id ?? "unknown";
|
|
30005
|
+
lines.push(`# ${name} (${id})`);
|
|
30006
|
+
lines.push("");
|
|
30007
|
+
if (meta) {
|
|
30008
|
+
lines.push(`- Model: ${meta.model}`);
|
|
30009
|
+
lines.push(`- Created: ${meta.createdAt}`);
|
|
30010
|
+
lines.push(`- Updated: ${meta.updatedAt}`);
|
|
30011
|
+
lines.push(`- Messages: ${meta.messageCount}`);
|
|
30012
|
+
if (meta.projectDir)
|
|
30013
|
+
lines.push(`- Project: ${meta.projectDir}`);
|
|
30014
|
+
}
|
|
30015
|
+
lines.push("");
|
|
30016
|
+
lines.push("---");
|
|
30017
|
+
lines.push("");
|
|
30018
|
+
for (const msg of messages) {
|
|
30019
|
+
const heading = roleHeading(msg.role);
|
|
30020
|
+
const nameSuffix = msg.name ? ` (${msg.name})` : "";
|
|
30021
|
+
lines.push(`## ${heading}${nameSuffix}`);
|
|
30022
|
+
lines.push("");
|
|
30023
|
+
const text = getMessageText(msg.content);
|
|
30024
|
+
lines.push(text.length > 0 ? text : "_(empty)_");
|
|
30025
|
+
lines.push("");
|
|
30026
|
+
if (Array.isArray(msg.tool_calls)) {
|
|
30027
|
+
for (const tc of msg.tool_calls) {
|
|
30028
|
+
lines.push(`- tool_call: \`${tc.function.name}\` ${tc.function.arguments}`);
|
|
30029
|
+
}
|
|
30030
|
+
lines.push("");
|
|
30031
|
+
}
|
|
30032
|
+
}
|
|
30033
|
+
return lines.join(`
|
|
30034
|
+
`);
|
|
30035
|
+
}
|
|
30036
|
+
function buildSessionJson(meta, messages) {
|
|
30037
|
+
return JSON.stringify({ meta, messages }, null, 2);
|
|
30038
|
+
}
|
|
30039
|
+
function buildSessionJsonl(log2) {
|
|
30040
|
+
return log2.map((e) => JSON.stringify(e)).join(`
|
|
30041
|
+
`);
|
|
30042
|
+
}
|
|
30043
|
+
function formatExport(bundle, format) {
|
|
30044
|
+
switch (format) {
|
|
30045
|
+
case "md":
|
|
30046
|
+
return renderSessionMarkdown(bundle.meta, bundle.messages);
|
|
30047
|
+
case "json":
|
|
30048
|
+
return buildSessionJson(bundle.meta, bundle.messages);
|
|
30049
|
+
case "jsonl":
|
|
30050
|
+
return buildSessionJsonl(bundle.log);
|
|
30051
|
+
}
|
|
30052
|
+
}
|
|
30053
|
+
function redactExport(text, redact) {
|
|
30054
|
+
return redact ? redactContextSecrets(text) : text;
|
|
30055
|
+
}
|
|
30056
|
+
function sanitizeFileName(name) {
|
|
30057
|
+
const cleaned = name.replace(/[<>:"/\\|?*\u0000-\u001f]/g, "-").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^[-.]+|[-.]+$/g, "");
|
|
30058
|
+
return cleaned.length > 0 ? cleaned.slice(0, 60) : "session";
|
|
30059
|
+
}
|
|
30060
|
+
function extensionFor(format) {
|
|
30061
|
+
return format === "jsonl" ? "jsonl" : format;
|
|
30062
|
+
}
|
|
30063
|
+
var init_export = __esm(() => {
|
|
30064
|
+
init_context_log();
|
|
30065
|
+
});
|
|
30066
|
+
|
|
29764
30067
|
// src/modules/indexer/map-command.ts
|
|
29765
30068
|
async function runMapAction(module, action, query) {
|
|
29766
30069
|
const summary = async () => {
|
|
@@ -38050,6 +38353,404 @@ var init_cli = __esm(() => {
|
|
|
38050
38353
|
MMA_ROOT = findMmaRoot(HERE);
|
|
38051
38354
|
});
|
|
38052
38355
|
|
|
38356
|
+
// src/config/registry.ts
|
|
38357
|
+
function shareField(key, canonical) {
|
|
38358
|
+
const field = key === "system" ? "systemPrompt" : "responseReserve";
|
|
38359
|
+
const other = key === "system" ? "responseReserve" : "systemPrompt";
|
|
38360
|
+
return {
|
|
38361
|
+
key: canonical,
|
|
38362
|
+
aliases: [`context.${key}`],
|
|
38363
|
+
domain: "budget",
|
|
38364
|
+
valueType: "share",
|
|
38365
|
+
reconfigure: true,
|
|
38366
|
+
get: (c) => c.contextBudget[field],
|
|
38367
|
+
set: (c, v) => setBudgetShare(c, key, v),
|
|
38368
|
+
extraValidate: (c, v) => {
|
|
38369
|
+
const n = v;
|
|
38370
|
+
const total = n + c.contextBudget[other];
|
|
38371
|
+
return total > MAX_COMBINED2 ? "combined" : null;
|
|
38372
|
+
}
|
|
38373
|
+
};
|
|
38374
|
+
}
|
|
38375
|
+
function resolveConfigKey(name) {
|
|
38376
|
+
return BY_NAME.get(name) ?? null;
|
|
38377
|
+
}
|
|
38378
|
+
function configDefs() {
|
|
38379
|
+
return DEFINITIONS;
|
|
38380
|
+
}
|
|
38381
|
+
function canonicalKeys() {
|
|
38382
|
+
return DEFINITIONS.map((d) => d.key);
|
|
38383
|
+
}
|
|
38384
|
+
function keysForGroup(prefix) {
|
|
38385
|
+
return DEFINITIONS.filter((d) => d.key.startsWith(prefix + "."));
|
|
38386
|
+
}
|
|
38387
|
+
function allConfigNames() {
|
|
38388
|
+
const out = [];
|
|
38389
|
+
for (const def of DEFINITIONS) {
|
|
38390
|
+
out.push({ name: def.key, def, alias: false });
|
|
38391
|
+
for (const a of def.aliases)
|
|
38392
|
+
out.push({ name: a, def, alias: true });
|
|
38393
|
+
}
|
|
38394
|
+
return out;
|
|
38395
|
+
}
|
|
38396
|
+
function formatConfigValue(value) {
|
|
38397
|
+
if (typeof value === "boolean")
|
|
38398
|
+
return value ? "on" : "off";
|
|
38399
|
+
return String(value);
|
|
38400
|
+
}
|
|
38401
|
+
function parseBool(raw) {
|
|
38402
|
+
const v = raw.trim().toLowerCase();
|
|
38403
|
+
if (["on", "true", "1", "yes", "y", "enable", "enabled"].includes(v))
|
|
38404
|
+
return { ok: true, value: true };
|
|
38405
|
+
if (["off", "false", "0", "no", "n", "disable", "disabled"].includes(v))
|
|
38406
|
+
return { ok: true, value: false };
|
|
38407
|
+
return { ok: false, reason: "invalid" };
|
|
38408
|
+
}
|
|
38409
|
+
function parseConfigValue(def, raw) {
|
|
38410
|
+
const trimmed = raw.trim();
|
|
38411
|
+
switch (def.valueType) {
|
|
38412
|
+
case "string":
|
|
38413
|
+
return trimmed.length > 0 ? { ok: true, value: trimmed } : { ok: false, reason: "invalid" };
|
|
38414
|
+
case "bool":
|
|
38415
|
+
return parseBool(trimmed);
|
|
38416
|
+
case "enum": {
|
|
38417
|
+
const v = trimmed.toLowerCase();
|
|
38418
|
+
if (def.enumValues && !def.enumValues.includes(v))
|
|
38419
|
+
return { ok: false, reason: "invalid" };
|
|
38420
|
+
return { ok: true, value: v };
|
|
38421
|
+
}
|
|
38422
|
+
case "int": {
|
|
38423
|
+
if (!/^-?\d+$/.test(trimmed))
|
|
38424
|
+
return { ok: false, reason: "invalid" };
|
|
38425
|
+
const n = Number(trimmed);
|
|
38426
|
+
if (!Number.isFinite(n))
|
|
38427
|
+
return { ok: false, reason: "invalid" };
|
|
38428
|
+
if (def.min !== undefined && n < def.min)
|
|
38429
|
+
return { ok: false, reason: "invalid" };
|
|
38430
|
+
if (def.max !== undefined && n > def.max)
|
|
38431
|
+
return { ok: false, reason: "invalid" };
|
|
38432
|
+
return { ok: true, value: n };
|
|
38433
|
+
}
|
|
38434
|
+
case "share": {
|
|
38435
|
+
const isPct = trimmed.endsWith("%");
|
|
38436
|
+
const body = isPct ? trimmed.slice(0, -1).trim() : trimmed;
|
|
38437
|
+
if (!/^-?\d+(\.\d+)?$/.test(body))
|
|
38438
|
+
return { ok: false, reason: "invalid" };
|
|
38439
|
+
let n = Number(body);
|
|
38440
|
+
if (isPct)
|
|
38441
|
+
n = n / 100;
|
|
38442
|
+
if (!Number.isFinite(n) || n < MIN_SHARE2 || n > MAX_SHARE2)
|
|
38443
|
+
return { ok: false, reason: "invalid" };
|
|
38444
|
+
return { ok: true, value: n };
|
|
38445
|
+
}
|
|
38446
|
+
}
|
|
38447
|
+
}
|
|
38448
|
+
function getConfigValue(config, name) {
|
|
38449
|
+
const def = resolveConfigKey(name);
|
|
38450
|
+
if (!def)
|
|
38451
|
+
return { ok: false, reason: "unknown-key", input: name };
|
|
38452
|
+
const value = def.get(config);
|
|
38453
|
+
return { ok: true, key: def.key, def, value, display: formatConfigValue(value) };
|
|
38454
|
+
}
|
|
38455
|
+
function setConfigValue(config, name, raw) {
|
|
38456
|
+
const def = resolveConfigKey(name);
|
|
38457
|
+
if (!def)
|
|
38458
|
+
return { ok: false, reason: "unknown-key", input: name };
|
|
38459
|
+
if (def.readOnly)
|
|
38460
|
+
return { ok: false, reason: "read-only", input: name, key: def.key, def };
|
|
38461
|
+
const parsed = parseConfigValue(def, raw);
|
|
38462
|
+
if (!parsed.ok)
|
|
38463
|
+
return { ok: false, reason: "invalid-value", input: name, key: def.key, def };
|
|
38464
|
+
const extra = def.extraValidate?.(config, parsed.value);
|
|
38465
|
+
if (extra)
|
|
38466
|
+
return { ok: false, reason: extra, input: name, key: def.key, def };
|
|
38467
|
+
def.set(config, parsed.value);
|
|
38468
|
+
return {
|
|
38469
|
+
ok: true,
|
|
38470
|
+
key: def.key,
|
|
38471
|
+
def,
|
|
38472
|
+
value: parsed.value,
|
|
38473
|
+
display: formatConfigValue(parsed.value),
|
|
38474
|
+
reconfigure: def.reconfigure,
|
|
38475
|
+
reasoningChanged: def.key === "reasoning.mode"
|
|
38476
|
+
};
|
|
38477
|
+
}
|
|
38478
|
+
function captureConfigSnapshot(config) {
|
|
38479
|
+
const snapshot = new Map;
|
|
38480
|
+
for (const def of DEFINITIONS) {
|
|
38481
|
+
try {
|
|
38482
|
+
snapshot.set(def.key, structuredClone(def.get(config)));
|
|
38483
|
+
} catch {}
|
|
38484
|
+
}
|
|
38485
|
+
return snapshot;
|
|
38486
|
+
}
|
|
38487
|
+
var REASONING_LEVELS, LOG_LEVELS, VERBOSITY_LEVELS, LOCALES, MIN_SHARE2 = 0.05, MAX_SHARE2 = 0.9, MAX_COMBINED2 = 0.95, DEFINITIONS, BY_NAME;
|
|
38488
|
+
var init_registry2 = __esm(() => {
|
|
38489
|
+
init_defaults();
|
|
38490
|
+
init_budget();
|
|
38491
|
+
REASONING_LEVELS = [
|
|
38492
|
+
"auto",
|
|
38493
|
+
"default",
|
|
38494
|
+
"none",
|
|
38495
|
+
"low",
|
|
38496
|
+
"medium",
|
|
38497
|
+
"high",
|
|
38498
|
+
"max"
|
|
38499
|
+
];
|
|
38500
|
+
LOG_LEVELS = ["silent", "error", "warn", "info", "debug"];
|
|
38501
|
+
VERBOSITY_LEVELS = ["quiet", "normal", "verbose"];
|
|
38502
|
+
LOCALES = ["en", "ru"];
|
|
38503
|
+
DEFINITIONS = [
|
|
38504
|
+
{
|
|
38505
|
+
key: "model",
|
|
38506
|
+
aliases: [],
|
|
38507
|
+
domain: "agent",
|
|
38508
|
+
valueType: "string",
|
|
38509
|
+
reconfigure: true,
|
|
38510
|
+
get: (c) => c.model,
|
|
38511
|
+
set: (c, v) => {
|
|
38512
|
+
c.model = String(v);
|
|
38513
|
+
}
|
|
38514
|
+
},
|
|
38515
|
+
{
|
|
38516
|
+
key: "provider.active",
|
|
38517
|
+
aliases: [],
|
|
38518
|
+
domain: "provider",
|
|
38519
|
+
valueType: "string",
|
|
38520
|
+
reconfigure: true,
|
|
38521
|
+
get: (c) => c.provider.active ?? c.provider.type,
|
|
38522
|
+
set: (c, v) => {
|
|
38523
|
+
c.provider.active = String(v);
|
|
38524
|
+
},
|
|
38525
|
+
extraValidate: (c, v) => {
|
|
38526
|
+
const entries = c.provider.entries ?? [];
|
|
38527
|
+
if (entries.length === 0)
|
|
38528
|
+
return null;
|
|
38529
|
+
const name = String(v);
|
|
38530
|
+
const found = entries.some((e) => e.label === name || e.type === name);
|
|
38531
|
+
return found ? null : "invalid";
|
|
38532
|
+
}
|
|
38533
|
+
},
|
|
38534
|
+
{
|
|
38535
|
+
key: "contextWindow",
|
|
38536
|
+
aliases: ["context.window"],
|
|
38537
|
+
domain: "budget",
|
|
38538
|
+
valueType: "int",
|
|
38539
|
+
min: 1024,
|
|
38540
|
+
reconfigure: true,
|
|
38541
|
+
get: (c) => c.contextWindow,
|
|
38542
|
+
set: (c, v) => {
|
|
38543
|
+
c.contextWindow = v;
|
|
38544
|
+
}
|
|
38545
|
+
},
|
|
38546
|
+
shareField("system", "contextBudget.systemPrompt"),
|
|
38547
|
+
shareField("reserve", "contextBudget.responseReserve"),
|
|
38548
|
+
{
|
|
38549
|
+
key: "showReasoning",
|
|
38550
|
+
aliases: ["reasoning.show"],
|
|
38551
|
+
domain: "reasoning",
|
|
38552
|
+
valueType: "bool",
|
|
38553
|
+
reconfigure: false,
|
|
38554
|
+
get: (c) => c.showReasoning,
|
|
38555
|
+
set: (c, v) => {
|
|
38556
|
+
c.showReasoning = v;
|
|
38557
|
+
}
|
|
38558
|
+
},
|
|
38559
|
+
{
|
|
38560
|
+
key: "reasoning.mode",
|
|
38561
|
+
aliases: ["reasoning.level"],
|
|
38562
|
+
domain: "reasoning",
|
|
38563
|
+
valueType: "enum",
|
|
38564
|
+
enumValues: REASONING_LEVELS,
|
|
38565
|
+
reconfigure: true,
|
|
38566
|
+
get: (c) => c.reasoning?.mode ?? "auto",
|
|
38567
|
+
set: (c, v) => {
|
|
38568
|
+
const base = c.reasoning ?? structuredClone(DEFAULTS.reasoning);
|
|
38569
|
+
c.reasoning = { ...base, mode: v };
|
|
38570
|
+
}
|
|
38571
|
+
},
|
|
38572
|
+
{
|
|
38573
|
+
key: "ui.verbosity",
|
|
38574
|
+
aliases: ["verbosity"],
|
|
38575
|
+
domain: "ui",
|
|
38576
|
+
valueType: "enum",
|
|
38577
|
+
enumValues: VERBOSITY_LEVELS,
|
|
38578
|
+
reconfigure: false,
|
|
38579
|
+
get: (c) => c.ui.verbosity ?? (c.ui.verbose ? "verbose" : "quiet"),
|
|
38580
|
+
set: (c, v) => {
|
|
38581
|
+
c.ui.verbosity = v;
|
|
38582
|
+
}
|
|
38583
|
+
},
|
|
38584
|
+
{
|
|
38585
|
+
key: "maxToolIterations",
|
|
38586
|
+
aliases: [],
|
|
38587
|
+
domain: "agent",
|
|
38588
|
+
valueType: "int",
|
|
38589
|
+
min: 1,
|
|
38590
|
+
reconfigure: false,
|
|
38591
|
+
get: (c) => c.maxToolIterations,
|
|
38592
|
+
set: (c, v) => {
|
|
38593
|
+
c.maxToolIterations = v;
|
|
38594
|
+
}
|
|
38595
|
+
},
|
|
38596
|
+
{
|
|
38597
|
+
key: "stuckThreshold",
|
|
38598
|
+
aliases: [],
|
|
38599
|
+
domain: "agent",
|
|
38600
|
+
valueType: "int",
|
|
38601
|
+
min: 1,
|
|
38602
|
+
reconfigure: false,
|
|
38603
|
+
get: (c) => c.stuckThreshold,
|
|
38604
|
+
set: (c, v) => {
|
|
38605
|
+
c.stuckThreshold = v;
|
|
38606
|
+
}
|
|
38607
|
+
},
|
|
38608
|
+
{
|
|
38609
|
+
key: "logLevel",
|
|
38610
|
+
aliases: [],
|
|
38611
|
+
domain: "agent",
|
|
38612
|
+
valueType: "enum",
|
|
38613
|
+
enumValues: LOG_LEVELS,
|
|
38614
|
+
reconfigure: false,
|
|
38615
|
+
get: (c) => c.logLevel,
|
|
38616
|
+
set: (c, v) => {
|
|
38617
|
+
c.logLevel = String(v);
|
|
38618
|
+
}
|
|
38619
|
+
},
|
|
38620
|
+
{
|
|
38621
|
+
key: "locale",
|
|
38622
|
+
aliases: [],
|
|
38623
|
+
domain: "i18n",
|
|
38624
|
+
valueType: "enum",
|
|
38625
|
+
enumValues: LOCALES,
|
|
38626
|
+
reconfigure: false,
|
|
38627
|
+
get: (c) => c.locale,
|
|
38628
|
+
set: (c, v) => {
|
|
38629
|
+
c.locale = String(v);
|
|
38630
|
+
}
|
|
38631
|
+
},
|
|
38632
|
+
{
|
|
38633
|
+
key: "version",
|
|
38634
|
+
aliases: [],
|
|
38635
|
+
domain: "agent",
|
|
38636
|
+
valueType: "string",
|
|
38637
|
+
reconfigure: false,
|
|
38638
|
+
readOnly: true,
|
|
38639
|
+
get: (c) => c.version
|
|
38640
|
+
}
|
|
38641
|
+
];
|
|
38642
|
+
BY_NAME = new Map;
|
|
38643
|
+
for (const def of DEFINITIONS) {
|
|
38644
|
+
BY_NAME.set(def.key, def);
|
|
38645
|
+
for (const alias of def.aliases)
|
|
38646
|
+
BY_NAME.set(alias, def);
|
|
38647
|
+
}
|
|
38648
|
+
});
|
|
38649
|
+
|
|
38650
|
+
// src/ui/theme.ts
|
|
38651
|
+
function resolveVerbosity(ui) {
|
|
38652
|
+
if (ui?.verbosity)
|
|
38653
|
+
return ui.verbosity;
|
|
38654
|
+
return ui?.verbose ? "verbose" : "quiet";
|
|
38655
|
+
}
|
|
38656
|
+
function toolCategory(tool) {
|
|
38657
|
+
for (const [category, tools] of Object.entries(CATEGORY_TOOLS)) {
|
|
38658
|
+
if (tools.has(tool))
|
|
38659
|
+
return category;
|
|
38660
|
+
}
|
|
38661
|
+
return "meta";
|
|
38662
|
+
}
|
|
38663
|
+
function toolAccent(tool) {
|
|
38664
|
+
switch (toolCategory(tool)) {
|
|
38665
|
+
case "recon":
|
|
38666
|
+
return pc.cyan;
|
|
38667
|
+
case "mutate":
|
|
38668
|
+
return pc.magenta;
|
|
38669
|
+
case "execute":
|
|
38670
|
+
return pc.blue;
|
|
38671
|
+
case "meta":
|
|
38672
|
+
default:
|
|
38673
|
+
return pc.dim;
|
|
38674
|
+
}
|
|
38675
|
+
}
|
|
38676
|
+
function actionMarkFor(tool) {
|
|
38677
|
+
return toolAccent(tool)(glyph.action);
|
|
38678
|
+
}
|
|
38679
|
+
function successMark() {
|
|
38680
|
+
return pc.green(glyph.success);
|
|
38681
|
+
}
|
|
38682
|
+
function failureMark() {
|
|
38683
|
+
return pc.red(glyph.failure);
|
|
38684
|
+
}
|
|
38685
|
+
function formatDuration(ms) {
|
|
38686
|
+
if (ms < 1000)
|
|
38687
|
+
return `${ms}ms`;
|
|
38688
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
38689
|
+
}
|
|
38690
|
+
var glyph, CATEGORY_TOOLS;
|
|
38691
|
+
var init_theme = __esm(() => {
|
|
38692
|
+
init_colors();
|
|
38693
|
+
glyph = {
|
|
38694
|
+
action: "◇",
|
|
38695
|
+
success: "✓",
|
|
38696
|
+
failure: "✗",
|
|
38697
|
+
warning: "⚠",
|
|
38698
|
+
thinking: "✦",
|
|
38699
|
+
question: "?",
|
|
38700
|
+
user: "↵",
|
|
38701
|
+
detail: "↳",
|
|
38702
|
+
group: "│",
|
|
38703
|
+
metric: "⟡",
|
|
38704
|
+
compact: "⟳"
|
|
38705
|
+
};
|
|
38706
|
+
CATEGORY_TOOLS = {
|
|
38707
|
+
recon: new Set([
|
|
38708
|
+
"read_file",
|
|
38709
|
+
"list_dir",
|
|
38710
|
+
"glob",
|
|
38711
|
+
"grep",
|
|
38712
|
+
"file_info",
|
|
38713
|
+
"project_map",
|
|
38714
|
+
"chunk_query",
|
|
38715
|
+
"web_search",
|
|
38716
|
+
"web_fetch",
|
|
38717
|
+
"web_browse",
|
|
38718
|
+
"search_history",
|
|
38719
|
+
"recall",
|
|
38720
|
+
"session_info",
|
|
38721
|
+
"process_list",
|
|
38722
|
+
"process_log"
|
|
38723
|
+
]),
|
|
38724
|
+
mutate: new Set([
|
|
38725
|
+
"write_file",
|
|
38726
|
+
"edit_file",
|
|
38727
|
+
"create_dir",
|
|
38728
|
+
"delete_file",
|
|
38729
|
+
"move_file",
|
|
38730
|
+
"attach_image"
|
|
38731
|
+
]),
|
|
38732
|
+
execute: new Set([
|
|
38733
|
+
"bash",
|
|
38734
|
+
"process_kill",
|
|
38735
|
+
"pipeline_run",
|
|
38736
|
+
"browser",
|
|
38737
|
+
"download_file",
|
|
38738
|
+
"subagent",
|
|
38739
|
+
"mcp_call"
|
|
38740
|
+
]),
|
|
38741
|
+
meta: new Set([
|
|
38742
|
+
"plan",
|
|
38743
|
+
"todo",
|
|
38744
|
+
"verify",
|
|
38745
|
+
"lsp_check",
|
|
38746
|
+
"enable_tools",
|
|
38747
|
+
"set_thinking",
|
|
38748
|
+
"load_skill",
|
|
38749
|
+
"remember"
|
|
38750
|
+
])
|
|
38751
|
+
};
|
|
38752
|
+
});
|
|
38753
|
+
|
|
38053
38754
|
// src/cli/repl-commands.ts
|
|
38054
38755
|
var exports_repl_commands = {};
|
|
38055
38756
|
__export(exports_repl_commands, {
|
|
@@ -38057,7 +38758,8 @@ __export(exports_repl_commands, {
|
|
|
38057
38758
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
38058
38759
|
});
|
|
38059
38760
|
import { join as join55, dirname as dirname25 } from "path";
|
|
38060
|
-
import { existsSync as existsSync60 } from "fs";
|
|
38761
|
+
import { existsSync as existsSync60, writeFileSync as writeFileSync25, mkdirSync as mkdirSync26 } from "fs";
|
|
38762
|
+
import { homedir as homedir18 } from "os";
|
|
38061
38763
|
function registerAllCommands(ctx) {
|
|
38062
38764
|
registerBuiltinCommands(ctx);
|
|
38063
38765
|
registerMmaCommands(ctx);
|
|
@@ -38069,7 +38771,8 @@ function registerBuiltinCommands(ctx) {
|
|
|
38069
38771
|
name: "help",
|
|
38070
38772
|
description: t("repl.help"),
|
|
38071
38773
|
usage: t("repl.help_usage"),
|
|
38072
|
-
|
|
38774
|
+
examples: ["/help", "/help config"],
|
|
38775
|
+
action: (args) => ctx.showHelp(args[0])
|
|
38073
38776
|
});
|
|
38074
38777
|
ctx.registerCommand({
|
|
38075
38778
|
name: "exit",
|
|
@@ -38084,6 +38787,7 @@ function registerBuiltinCommands(ctx) {
|
|
|
38084
38787
|
usage: t("repl.clear_usage"),
|
|
38085
38788
|
action: () => {
|
|
38086
38789
|
ctx.output.clearScreen();
|
|
38790
|
+
ctx.output.writeLine(pc.dim(t("repl.clear_hint")));
|
|
38087
38791
|
}
|
|
38088
38792
|
});
|
|
38089
38793
|
}
|
|
@@ -38159,36 +38863,267 @@ function registerRunCommands(ctx) {
|
|
|
38159
38863
|
}
|
|
38160
38864
|
});
|
|
38161
38865
|
}
|
|
38866
|
+
function changeHint(def) {
|
|
38867
|
+
if (def.readOnly)
|
|
38868
|
+
return t("config.read_only_hint");
|
|
38869
|
+
return SUGAR_HINTS[def.key] ?? `/config ${def.key} <value>`;
|
|
38870
|
+
}
|
|
38871
|
+
function configValueHint(def) {
|
|
38872
|
+
if (!def)
|
|
38873
|
+
return "";
|
|
38874
|
+
switch (def.valueType) {
|
|
38875
|
+
case "enum":
|
|
38876
|
+
return t("config.hint_enum", { values: (def.enumValues ?? []).join(", ") });
|
|
38877
|
+
case "bool":
|
|
38878
|
+
return t("config.hint_bool");
|
|
38879
|
+
case "share":
|
|
38880
|
+
return t("config.hint_share");
|
|
38881
|
+
case "int":
|
|
38882
|
+
return t("config.hint_int", { min: String(def.min ?? 1) });
|
|
38883
|
+
default:
|
|
38884
|
+
return t("config.hint_string");
|
|
38885
|
+
}
|
|
38886
|
+
}
|
|
38887
|
+
function editDistance(a, b) {
|
|
38888
|
+
const dp = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
38889
|
+
for (let i = 1;i <= a.length; i++) {
|
|
38890
|
+
let prev = dp[0];
|
|
38891
|
+
dp[0] = i;
|
|
38892
|
+
for (let j = 1;j <= b.length; j++) {
|
|
38893
|
+
const tmp = dp[j];
|
|
38894
|
+
dp[j] = Math.min(dp[j] + 1, dp[j - 1] + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
38895
|
+
prev = tmp;
|
|
38896
|
+
}
|
|
38897
|
+
}
|
|
38898
|
+
return dp[b.length];
|
|
38899
|
+
}
|
|
38900
|
+
function nearestConfigKey(input) {
|
|
38901
|
+
const names = canonicalKeys();
|
|
38902
|
+
let best = null;
|
|
38903
|
+
for (const name of names) {
|
|
38904
|
+
const d = editDistance(input.toLowerCase(), name.toLowerCase());
|
|
38905
|
+
if (best === null || d < best.dist)
|
|
38906
|
+
best = { name, dist: d };
|
|
38907
|
+
}
|
|
38908
|
+
if (!best)
|
|
38909
|
+
return null;
|
|
38910
|
+
const threshold = Math.max(2, Math.floor(best.name.length / 3));
|
|
38911
|
+
return best.dist <= threshold ? best.name : null;
|
|
38912
|
+
}
|
|
38913
|
+
function renderConfigError(ctx, result) {
|
|
38914
|
+
const key = result.key ?? result.input;
|
|
38915
|
+
switch (result.reason) {
|
|
38916
|
+
case "unknown-key": {
|
|
38917
|
+
const suggestion = nearestConfigKey(result.input);
|
|
38918
|
+
const suffix = suggestion ? t("config.suggest", { name: suggestion }) : t("config.valid_keys", { keys: canonicalKeys().join(", ") });
|
|
38919
|
+
ctx.output.writeLine(pc.yellow(t("config.unknown_key", { key: result.input, suggestion: suffix })), "stderr");
|
|
38920
|
+
return;
|
|
38921
|
+
}
|
|
38922
|
+
case "read-only":
|
|
38923
|
+
ctx.output.writeLine(pc.yellow(t("config.read_only", { key })), "stderr");
|
|
38924
|
+
return;
|
|
38925
|
+
case "range":
|
|
38926
|
+
ctx.output.writeLine(pc.yellow(t("config.range", { key })), "stderr");
|
|
38927
|
+
return;
|
|
38928
|
+
case "combined":
|
|
38929
|
+
ctx.output.writeLine(pc.yellow(t("config.combined")), "stderr");
|
|
38930
|
+
return;
|
|
38931
|
+
default:
|
|
38932
|
+
ctx.output.writeLine(pc.yellow(t("config.invalid_value", { key, hint: configValueHint(result.def) })), "stderr");
|
|
38933
|
+
}
|
|
38934
|
+
}
|
|
38935
|
+
function applyConfigSideEffects(ctx, result) {
|
|
38936
|
+
if (result.key === "ui.verbosity") {
|
|
38937
|
+
ctx.output.setSuppressInfoLogs(result.value === "quiet");
|
|
38938
|
+
} else if (result.key === "reasoning.mode") {
|
|
38939
|
+
ctx.agent.setReasoningLevel(result.value);
|
|
38940
|
+
} else if (result.key === "locale") {
|
|
38941
|
+
setLocale(result.value);
|
|
38942
|
+
}
|
|
38943
|
+
}
|
|
38944
|
+
function persistConfig(ctx) {
|
|
38945
|
+
const configPath = join55(ctx.configDir, "config.json");
|
|
38946
|
+
saveConfig(ctx.config, configPath, dirname25(configPath));
|
|
38947
|
+
}
|
|
38948
|
+
async function mutateConfig(ctx, key, raw) {
|
|
38949
|
+
const result = setConfigValue(ctx.config, key, raw);
|
|
38950
|
+
if (!result.ok)
|
|
38951
|
+
return result;
|
|
38952
|
+
applyConfigSideEffects(ctx, result);
|
|
38953
|
+
persistConfig(ctx);
|
|
38954
|
+
if (result.reconfigure)
|
|
38955
|
+
await ctx.agent.reconfigure(ctx.config);
|
|
38956
|
+
if (result.key === "locale")
|
|
38957
|
+
ctx.reregisterCommands();
|
|
38958
|
+
return result;
|
|
38959
|
+
}
|
|
38960
|
+
function reportSaved(ctx, result) {
|
|
38961
|
+
ctx.output.writeLine(pc.green(t("config.saved", { key: result.key })));
|
|
38962
|
+
}
|
|
38963
|
+
function rawFromValue(value) {
|
|
38964
|
+
if (typeof value === "boolean")
|
|
38965
|
+
return value ? "on" : "off";
|
|
38966
|
+
return String(value);
|
|
38967
|
+
}
|
|
38968
|
+
function printConfigTable(ctx, defs) {
|
|
38969
|
+
const list = defs ?? configDefs();
|
|
38970
|
+
const rows = list.map((def) => [
|
|
38971
|
+
def.key,
|
|
38972
|
+
formatConfigValue(def.get(ctx.config)),
|
|
38973
|
+
def.domain,
|
|
38974
|
+
changeHint(def)
|
|
38975
|
+
]);
|
|
38976
|
+
ctx.output.writeLine(pc.bold(t("config.header")));
|
|
38977
|
+
for (const line of renderTable([
|
|
38978
|
+
t("config.col_setting"),
|
|
38979
|
+
t("config.col_value"),
|
|
38980
|
+
t("config.col_domain"),
|
|
38981
|
+
t("config.col_change")
|
|
38982
|
+
], rows)) {
|
|
38983
|
+
ctx.output.writeLine(line);
|
|
38984
|
+
}
|
|
38985
|
+
const meta = ctx.sessionManager?.getActiveMeta();
|
|
38986
|
+
if (meta) {
|
|
38987
|
+
ctx.output.writeLine(pc.dim(t("config.session_line", {
|
|
38988
|
+
name: meta.name,
|
|
38989
|
+
id: meta.id,
|
|
38990
|
+
count: String(meta.messageCount)
|
|
38991
|
+
})));
|
|
38992
|
+
}
|
|
38993
|
+
ctx.output.writeLine(pc.dim(t("config.usage_hint")));
|
|
38994
|
+
}
|
|
38995
|
+
function confirm(ctx, prompt) {
|
|
38996
|
+
return new Promise((resolve25) => {
|
|
38997
|
+
ctx.withExclusiveInput(async () => {
|
|
38998
|
+
await new Promise((done) => {
|
|
38999
|
+
ctx.rl.question(prompt, (answer) => {
|
|
39000
|
+
resolve25(/^y(es)?$/i.test(answer.trim()));
|
|
39001
|
+
done();
|
|
39002
|
+
});
|
|
39003
|
+
});
|
|
39004
|
+
});
|
|
39005
|
+
});
|
|
39006
|
+
}
|
|
39007
|
+
async function runConfigReset(ctx, rest) {
|
|
39008
|
+
const snapshot = ctx.getConfigSnapshot();
|
|
39009
|
+
const yes = rest.includes("--yes");
|
|
39010
|
+
const all = rest.includes("--all");
|
|
39011
|
+
const target = rest.find((a) => !a.startsWith("--"));
|
|
39012
|
+
if (all) {
|
|
39013
|
+
const changed = canonicalKeys().filter((k) => {
|
|
39014
|
+
const def2 = resolveConfigKey(k);
|
|
39015
|
+
if (!def2 || !snapshot.has(k))
|
|
39016
|
+
return false;
|
|
39017
|
+
return rawFromValue(def2.get(ctx.config)) !== rawFromValue(snapshot.get(k));
|
|
39018
|
+
});
|
|
39019
|
+
if (changed.length === 0) {
|
|
39020
|
+
ctx.output.writeLine(t("config.reset_none"));
|
|
39021
|
+
return;
|
|
39022
|
+
}
|
|
39023
|
+
if (!yes) {
|
|
39024
|
+
if (!process.stdin.isTTY) {
|
|
39025
|
+
ctx.output.writeLine(pc.yellow(t("config.reset_all_needs_yes")), "stderr");
|
|
39026
|
+
return;
|
|
39027
|
+
}
|
|
39028
|
+
const ok = await confirm(ctx, t("config.reset_all_confirm", { count: String(changed.length) }));
|
|
39029
|
+
if (!ok) {
|
|
39030
|
+
ctx.output.writeLine(t("config.reset_cancelled"));
|
|
39031
|
+
return;
|
|
39032
|
+
}
|
|
39033
|
+
}
|
|
39034
|
+
let anyReconfig = false;
|
|
39035
|
+
let localeChanged = false;
|
|
39036
|
+
for (const k of changed) {
|
|
39037
|
+
const result2 = setConfigValue(ctx.config, k, rawFromValue(snapshot.get(k)));
|
|
39038
|
+
if (result2.ok) {
|
|
39039
|
+
applyConfigSideEffects(ctx, result2);
|
|
39040
|
+
anyReconfig = anyReconfig || result2.reconfigure;
|
|
39041
|
+
localeChanged = localeChanged || result2.key === "locale";
|
|
39042
|
+
}
|
|
39043
|
+
}
|
|
39044
|
+
persistConfig(ctx);
|
|
39045
|
+
if (anyReconfig)
|
|
39046
|
+
await ctx.agent.reconfigure(ctx.config);
|
|
39047
|
+
if (localeChanged)
|
|
39048
|
+
ctx.reregisterCommands();
|
|
39049
|
+
ctx.output.writeLine(pc.green(t("config.reset_all_done", { count: String(changed.length) })));
|
|
39050
|
+
return;
|
|
39051
|
+
}
|
|
39052
|
+
if (!target) {
|
|
39053
|
+
ctx.output.writeLine(t("config.reset_usage"));
|
|
39054
|
+
return;
|
|
39055
|
+
}
|
|
39056
|
+
const def = resolveConfigKey(target);
|
|
39057
|
+
if (!def) {
|
|
39058
|
+
renderConfigError(ctx, { reason: "unknown-key", input: target });
|
|
39059
|
+
return;
|
|
39060
|
+
}
|
|
39061
|
+
if (def.readOnly || !snapshot.has(def.key)) {
|
|
39062
|
+
ctx.output.writeLine(t("config.reset_unchanged", { key: def.key }));
|
|
39063
|
+
return;
|
|
39064
|
+
}
|
|
39065
|
+
if (rawFromValue(def.get(ctx.config)) === rawFromValue(snapshot.get(def.key))) {
|
|
39066
|
+
ctx.output.writeLine(t("config.reset_unchanged", { key: def.key }));
|
|
39067
|
+
return;
|
|
39068
|
+
}
|
|
39069
|
+
const result = await mutateConfig(ctx, def.key, rawFromValue(snapshot.get(def.key)));
|
|
39070
|
+
if (!result.ok) {
|
|
39071
|
+
renderConfigError(ctx, result);
|
|
39072
|
+
return;
|
|
39073
|
+
}
|
|
39074
|
+
ctx.output.writeLine(pc.green(t("config.reset_ok", { key: result.key, value: result.display })));
|
|
39075
|
+
}
|
|
39076
|
+
function printReasoningStatus(ctx) {
|
|
39077
|
+
const display = ctx.config.showReasoning ? t("reasoning.on") : t("reasoning.off");
|
|
39078
|
+
const mode = ctx.config.reasoning?.mode ?? "auto";
|
|
39079
|
+
const auto = mode === "auto" ? t("reasoning.auto_on") : t("reasoning.auto_off");
|
|
39080
|
+
ctx.output.writeLine(t("reasoning.status", { display, level: mode, auto }));
|
|
39081
|
+
}
|
|
38162
39082
|
function registerConfigCommands(ctx) {
|
|
38163
39083
|
ctx.registerCommand({
|
|
38164
39084
|
name: "config",
|
|
38165
39085
|
description: t("repl.config"),
|
|
38166
39086
|
usage: t("repl.config_usage"),
|
|
38167
|
-
|
|
39087
|
+
examples: ["/config", "/config model", "/config reasoning.mode high", "/config reset ui.verbosity"],
|
|
39088
|
+
action: async (args) => {
|
|
38168
39089
|
if ((args[0] ?? "").trim().toLowerCase() === "migrate") {
|
|
38169
39090
|
return runConfigMigrate(ctx);
|
|
38170
39091
|
}
|
|
38171
|
-
|
|
38172
|
-
|
|
38173
|
-
|
|
38174
|
-
|
|
38175
|
-
|
|
38176
|
-
|
|
38177
|
-
|
|
38178
|
-
|
|
38179
|
-
|
|
38180
|
-
|
|
38181
|
-
|
|
38182
|
-
|
|
38183
|
-
|
|
38184
|
-
|
|
38185
|
-
|
|
38186
|
-
|
|
38187
|
-
|
|
38188
|
-
|
|
38189
|
-
|
|
38190
|
-
|
|
38191
|
-
ctx.output.writeLine(`${
|
|
39092
|
+
if (args.length === 0) {
|
|
39093
|
+
printConfigTable(ctx);
|
|
39094
|
+
return;
|
|
39095
|
+
}
|
|
39096
|
+
if (args[0] === "reset") {
|
|
39097
|
+
await runConfigReset(ctx, args.slice(1));
|
|
39098
|
+
return;
|
|
39099
|
+
}
|
|
39100
|
+
const name = args[0];
|
|
39101
|
+
if (args.length === 1) {
|
|
39102
|
+
const group = keysForGroup(name);
|
|
39103
|
+
if (group.length > 0) {
|
|
39104
|
+
printConfigTable(ctx, group);
|
|
39105
|
+
return;
|
|
39106
|
+
}
|
|
39107
|
+
const got = getConfigValue(ctx.config, name);
|
|
39108
|
+
if (!got.ok) {
|
|
39109
|
+
renderConfigError(ctx, got);
|
|
39110
|
+
return;
|
|
39111
|
+
}
|
|
39112
|
+
ctx.output.writeLine(`${got.key} = ${got.display}`);
|
|
39113
|
+
return;
|
|
39114
|
+
}
|
|
39115
|
+
const raw = args.slice(1).join(" ");
|
|
39116
|
+
const result = await mutateConfig(ctx, name, raw);
|
|
39117
|
+
if (!result.ok) {
|
|
39118
|
+
renderConfigError(ctx, result);
|
|
39119
|
+
return;
|
|
39120
|
+
}
|
|
39121
|
+
reportSaved(ctx, result);
|
|
39122
|
+
if (result.key === "model") {
|
|
39123
|
+
const known = ctx.knownModels();
|
|
39124
|
+
if (known.length > 0 && !known.includes(String(result.value))) {
|
|
39125
|
+
ctx.output.writeLine(pc.yellow(t("model.not_in_list", { name: String(result.value) })));
|
|
39126
|
+
}
|
|
38192
39127
|
}
|
|
38193
39128
|
}
|
|
38194
39129
|
});
|
|
@@ -38196,37 +39131,60 @@ function registerConfigCommands(ctx) {
|
|
|
38196
39131
|
name: "reasoning",
|
|
38197
39132
|
description: t("repl.reasoning"),
|
|
38198
39133
|
usage: t("repl.reasoning_usage"),
|
|
38199
|
-
|
|
38200
|
-
|
|
38201
|
-
const
|
|
38202
|
-
if (!
|
|
38203
|
-
ctx
|
|
38204
|
-
|
|
38205
|
-
ctx.output.writeLine(t("repl.reasoning_status", { status }));
|
|
38206
|
-
} else if (VALID_LEVELS2.includes(level)) {
|
|
38207
|
-
ctx.agent.setReasoningLevel(level);
|
|
38208
|
-
ctx.output.writeLine(pc.green(t("repl.reasoning_level_set", { level })));
|
|
38209
|
-
} else {
|
|
38210
|
-
ctx.output.writeLine(pc.yellow(t("repl.reasoning_invalid_level", { level, valid: VALID_LEVELS2.join(", ") })));
|
|
39134
|
+
examples: ["/reasoning", "/reasoning show", "/reasoning level high"],
|
|
39135
|
+
action: async (args) => {
|
|
39136
|
+
const sub = args[0]?.trim().toLowerCase();
|
|
39137
|
+
if (!sub) {
|
|
39138
|
+
printReasoningStatus(ctx);
|
|
39139
|
+
return;
|
|
38211
39140
|
}
|
|
39141
|
+
if (sub === "show" || sub === "on" || sub === "hide" || sub === "off") {
|
|
39142
|
+
const on = sub === "show" || sub === "on";
|
|
39143
|
+
const result = await mutateConfig(ctx, "showReasoning", on ? "on" : "off");
|
|
39144
|
+
if (!result.ok) {
|
|
39145
|
+
renderConfigError(ctx, result);
|
|
39146
|
+
return;
|
|
39147
|
+
}
|
|
39148
|
+
ctx.output.writeLine(pc.green(t("reasoning.display_set", { state: on ? t("reasoning.on") : t("reasoning.off") })));
|
|
39149
|
+
return;
|
|
39150
|
+
}
|
|
39151
|
+
if (sub === "level") {
|
|
39152
|
+
const lvl = args[1]?.trim().toLowerCase();
|
|
39153
|
+
if (!lvl) {
|
|
39154
|
+
ctx.output.writeLine(t("repl.reasoning_usage"));
|
|
39155
|
+
return;
|
|
39156
|
+
}
|
|
39157
|
+
const result = await mutateConfig(ctx, "reasoning.mode", lvl);
|
|
39158
|
+
if (!result.ok) {
|
|
39159
|
+
renderConfigError(ctx, result);
|
|
39160
|
+
return;
|
|
39161
|
+
}
|
|
39162
|
+
ctx.output.writeLine(pc.green(t("repl.reasoning_level_set", { level: lvl })));
|
|
39163
|
+
if (lvl !== "auto")
|
|
39164
|
+
ctx.output.writeLine(pc.dim(t("reasoning.auto_off_hint")));
|
|
39165
|
+
return;
|
|
39166
|
+
}
|
|
39167
|
+
ctx.output.writeLine(pc.yellow(t("reasoning.unknown_sub", { sub })));
|
|
39168
|
+
ctx.output.writeLine(t("repl.reasoning_usage"));
|
|
38212
39169
|
}
|
|
38213
39170
|
});
|
|
38214
39171
|
ctx.registerCommand({
|
|
38215
39172
|
name: "verbose",
|
|
38216
39173
|
description: t("repl.verbose"),
|
|
38217
39174
|
usage: t("repl.verbose_usage"),
|
|
38218
|
-
|
|
38219
|
-
|
|
39175
|
+
examples: ["/verbose", "/verbose normal"],
|
|
39176
|
+
action: async (args) => {
|
|
38220
39177
|
const level = args[0]?.trim().toLowerCase();
|
|
38221
|
-
if (
|
|
38222
|
-
ctx.output.writeLine(
|
|
39178
|
+
if (!level) {
|
|
39179
|
+
ctx.output.writeLine(t("verbose.status", { level: resolveVerbosity(ctx.config.ui) }));
|
|
39180
|
+
return;
|
|
39181
|
+
}
|
|
39182
|
+
const result = await mutateConfig(ctx, "ui.verbosity", level);
|
|
39183
|
+
if (!result.ok) {
|
|
39184
|
+
renderConfigError(ctx, result);
|
|
38223
39185
|
return;
|
|
38224
39186
|
}
|
|
38225
|
-
|
|
38226
|
-
const next = level ?? (current === "verbose" ? "quiet" : "verbose");
|
|
38227
|
-
ctx.config.ui.verbosity = next;
|
|
38228
|
-
ctx.output.setSuppressInfoLogs(next === "quiet");
|
|
38229
|
-
ctx.output.writeLine(pc.green(t("repl.verbose_set", { level: next })));
|
|
39187
|
+
ctx.output.writeLine(pc.green(t("repl.verbose_set", { level: result.display })));
|
|
38230
39188
|
}
|
|
38231
39189
|
});
|
|
38232
39190
|
ctx.registerCommand({
|
|
@@ -38236,16 +39194,13 @@ function registerConfigCommands(ctx) {
|
|
|
38236
39194
|
action: () => {
|
|
38237
39195
|
const providers = ctx.agent.listProviders();
|
|
38238
39196
|
const active = providers.find((p) => p.active);
|
|
38239
|
-
|
|
38240
|
-
|
|
38241
|
-
ctx.output.writeLine(`${t("repl.provider")} ${active.label} (${pc.dim(active.type)}) @ ${pc.dim(active.baseUrl)}`);
|
|
38242
|
-
} else {
|
|
38243
|
-
ctx.output.writeLine(`${t("repl.provider")} ${ctx.config.provider.type} @ ${pc.dim(ctx.config.provider.baseUrl)}`);
|
|
38244
|
-
}
|
|
39197
|
+
const providerLabel = active ? active.label : ctx.config.provider.type;
|
|
39198
|
+
const parts = [ctx.config.model, providerLabel];
|
|
38245
39199
|
const meta = ctx.sessionManager?.getActiveMeta();
|
|
38246
|
-
if (meta)
|
|
38247
|
-
|
|
38248
|
-
}
|
|
39200
|
+
if (meta)
|
|
39201
|
+
parts.push(`${meta.name} (${meta.messageCount} ${t("repl.msgs")})`);
|
|
39202
|
+
parts.push(`${ctx.config.contextWindow} tok`);
|
|
39203
|
+
ctx.output.writeLine(parts.join(pc.dim(" · ")));
|
|
38249
39204
|
}
|
|
38250
39205
|
});
|
|
38251
39206
|
ctx.registerCommand({
|
|
@@ -38268,22 +39223,28 @@ function registerConfigCommands(ctx) {
|
|
|
38268
39223
|
ctx.registerCommand({
|
|
38269
39224
|
name: "sysprompt",
|
|
38270
39225
|
description: t("repl.sysprompt_desc"),
|
|
38271
|
-
usage: t("repl.
|
|
38272
|
-
|
|
39226
|
+
usage: t("repl.sysprompt_usage"),
|
|
39227
|
+
examples: ["/sysprompt", "/sysprompt --full"],
|
|
39228
|
+
action: (args) => {
|
|
38273
39229
|
const info = ctx.agent.getSystemPromptInfo();
|
|
39230
|
+
const full = args.includes("--full");
|
|
38274
39231
|
ctx.output.writeLine(pc.bold(t("repl.sysprompt_tokens", { count: String(info.tokenCount) })));
|
|
38275
|
-
ctx.output.writeLine(pc.dim("─".repeat(60)));
|
|
38276
|
-
for (const line of info.text.split(`
|
|
38277
|
-
`)) {
|
|
38278
|
-
ctx.output.writeLine(line);
|
|
38279
|
-
}
|
|
38280
|
-
ctx.output.writeLine(pc.dim("─".repeat(60)));
|
|
38281
39232
|
if (info.excluded.length > 0) {
|
|
38282
39233
|
ctx.output.writeLine(pc.yellow(t("repl.excluded_blocks", { count: String(info.excluded.length) })));
|
|
38283
39234
|
for (const e of info.excluded) {
|
|
38284
39235
|
ctx.output.writeLine(pc.dim(` - ${e.slice(0, 80)}${e.length > 80 ? "..." : ""}`));
|
|
38285
39236
|
}
|
|
38286
39237
|
}
|
|
39238
|
+
if (full) {
|
|
39239
|
+
ctx.output.writeLine(pc.dim("─".repeat(60)));
|
|
39240
|
+
for (const line of info.text.split(`
|
|
39241
|
+
`)) {
|
|
39242
|
+
ctx.output.writeLine(line);
|
|
39243
|
+
}
|
|
39244
|
+
ctx.output.writeLine(pc.dim("─".repeat(60)));
|
|
39245
|
+
} else {
|
|
39246
|
+
ctx.output.writeLine(pc.dim(t("repl.sysprompt_full_hint")));
|
|
39247
|
+
}
|
|
38287
39248
|
}
|
|
38288
39249
|
});
|
|
38289
39250
|
ctx.registerCommand({
|
|
@@ -38323,13 +39284,14 @@ function registerProviderCommands(ctx) {
|
|
|
38323
39284
|
ctx.output.writeLine(t("repl.provider_usage"));
|
|
38324
39285
|
return;
|
|
38325
39286
|
}
|
|
38326
|
-
|
|
38327
|
-
|
|
38328
|
-
ctx
|
|
38329
|
-
|
|
38330
|
-
} catch (e) {
|
|
38331
|
-
ctx.output.writeLine(pc.red(e.message), "stderr");
|
|
39287
|
+
const result = await mutateConfig(ctx, "provider.active", name);
|
|
39288
|
+
if (!result.ok) {
|
|
39289
|
+
renderConfigError(ctx, result);
|
|
39290
|
+
return;
|
|
38332
39291
|
}
|
|
39292
|
+
ctx.refreshModelCache();
|
|
39293
|
+
ctx.output.writeLine(pc.green(t("repl.provider_set", { name })));
|
|
39294
|
+
reportSaved(ctx, result);
|
|
38333
39295
|
};
|
|
38334
39296
|
const add = async (args) => {
|
|
38335
39297
|
const flags = {};
|
|
@@ -38352,6 +39314,13 @@ function registerProviderCommands(ctx) {
|
|
|
38352
39314
|
ctx.output.writeLine(t("repl.provider_usage"));
|
|
38353
39315
|
return;
|
|
38354
39316
|
}
|
|
39317
|
+
for (const flag of ["priority", "context-window", "rpm", "parallel"]) {
|
|
39318
|
+
const v = flags[flag];
|
|
39319
|
+
if (v !== undefined && !Number.isFinite(Number(v))) {
|
|
39320
|
+
ctx.output.writeLine(pc.red(t("repl.provider_add_invalid_number", { flag: `--${flag}`, value: v })), "stderr");
|
|
39321
|
+
return;
|
|
39322
|
+
}
|
|
39323
|
+
}
|
|
38355
39324
|
const entries = Array.isArray(ctx.config.provider.entries) ? ctx.config.provider.entries : [];
|
|
38356
39325
|
if (entries.length === 0) {
|
|
38357
39326
|
entries.push({
|
|
@@ -38382,8 +39351,7 @@ function registerProviderCommands(ctx) {
|
|
|
38382
39351
|
});
|
|
38383
39352
|
ctx.config.provider.entries = entries;
|
|
38384
39353
|
ctx.config.provider.active = ctx.config.provider.active || ctx.config.provider.type;
|
|
38385
|
-
|
|
38386
|
-
saveConfig(ctx.config, configPath, dirname25(configPath));
|
|
39354
|
+
persistConfig(ctx);
|
|
38387
39355
|
await ctx.agent.reconfigure(ctx.config);
|
|
38388
39356
|
ctx.output.writeLine(pc.green(t("cli.provider_added", { name })));
|
|
38389
39357
|
ctx.output.writeLine(t("repl.provider_switch_hint", { name }));
|
|
@@ -38397,10 +39365,12 @@ function registerProviderCommands(ctx) {
|
|
|
38397
39365
|
name: "provider",
|
|
38398
39366
|
description: t("repl.provider_list"),
|
|
38399
39367
|
usage: t("repl.provider_usage"),
|
|
39368
|
+
examples: ["/provider list", "/provider use openrouter", "/provider add openai --key sk-..."],
|
|
38400
39369
|
action: async (args) => {
|
|
38401
39370
|
const subcmd = args[0];
|
|
38402
39371
|
const handler = subcmd ? handlers[subcmd] : handlers.list;
|
|
38403
39372
|
if (!handler) {
|
|
39373
|
+
ctx.output.writeLine(pc.yellow(t("repl.unknown_sub", { cmd: "provider", sub: subcmd })));
|
|
38404
39374
|
ctx.output.writeLine(t("repl.provider_usage"));
|
|
38405
39375
|
return;
|
|
38406
39376
|
}
|
|
@@ -38448,11 +39418,17 @@ function registerProviderCommands(ctx) {
|
|
|
38448
39418
|
ctx.output.writeLine(t("repl.model_usage"));
|
|
38449
39419
|
return;
|
|
38450
39420
|
}
|
|
38451
|
-
ctx
|
|
38452
|
-
|
|
38453
|
-
|
|
38454
|
-
|
|
39421
|
+
const result = await mutateConfig(ctx, "model", name);
|
|
39422
|
+
if (!result.ok) {
|
|
39423
|
+
renderConfigError(ctx, result);
|
|
39424
|
+
return;
|
|
39425
|
+
}
|
|
38455
39426
|
ctx.output.writeLine(pc.green(t("repl.model_set", { name })));
|
|
39427
|
+
const known = ctx.knownModels();
|
|
39428
|
+
if (known.length > 0 && !known.includes(name)) {
|
|
39429
|
+
ctx.output.writeLine(pc.yellow(t("model.not_in_list", { name })));
|
|
39430
|
+
}
|
|
39431
|
+
reportSaved(ctx, result);
|
|
38456
39432
|
};
|
|
38457
39433
|
const modelHandlers = {
|
|
38458
39434
|
list: listModels,
|
|
@@ -38462,10 +39438,12 @@ function registerProviderCommands(ctx) {
|
|
|
38462
39438
|
name: "model",
|
|
38463
39439
|
description: t("repl.model_list"),
|
|
38464
39440
|
usage: t("repl.model_usage"),
|
|
39441
|
+
examples: ["/model list", "/model use qwen/qwen3.5-9b"],
|
|
38465
39442
|
action: async (args) => {
|
|
38466
39443
|
const subcmd = args[0];
|
|
38467
39444
|
const handler = subcmd ? modelHandlers[subcmd] : modelHandlers.list;
|
|
38468
39445
|
if (!handler) {
|
|
39446
|
+
ctx.output.writeLine(pc.yellow(t("repl.unknown_sub", { cmd: "model", sub: subcmd })));
|
|
38469
39447
|
ctx.output.writeLine(t("repl.model_usage"));
|
|
38470
39448
|
return;
|
|
38471
39449
|
}
|
|
@@ -38476,12 +39454,8 @@ function registerProviderCommands(ctx) {
|
|
|
38476
39454
|
name: "context",
|
|
38477
39455
|
description: t("cli.manage_context"),
|
|
38478
39456
|
usage: t("repl.context_usage"),
|
|
39457
|
+
examples: ["/context", "/context 64000", "/context system 10%", "/context reserve 0.2"],
|
|
38479
39458
|
action: async (args) => {
|
|
38480
|
-
const save = async () => {
|
|
38481
|
-
const configPath = join55(ctx.configDir, "config.json");
|
|
38482
|
-
saveConfig(ctx.config, configPath, dirname25(configPath));
|
|
38483
|
-
await ctx.agent.reconfigure(ctx.config);
|
|
38484
|
-
};
|
|
38485
39459
|
if (args.length === 0) {
|
|
38486
39460
|
for (const line of budgetBreakdownLines(ctx.config))
|
|
38487
39461
|
ctx.output.writeLine(line);
|
|
@@ -38489,24 +39463,32 @@ function registerProviderCommands(ctx) {
|
|
|
38489
39463
|
return;
|
|
38490
39464
|
}
|
|
38491
39465
|
if (args[0] === "system" || args[0] === "reserve") {
|
|
38492
|
-
const
|
|
38493
|
-
|
|
38494
|
-
|
|
38495
|
-
ctx.output.writeLine(pc.yellow(t("cli.context_invalid_fraction")));
|
|
39466
|
+
const raw = args[1];
|
|
39467
|
+
if (!raw) {
|
|
39468
|
+
ctx.output.writeLine(t("repl.context_usage"));
|
|
38496
39469
|
return;
|
|
38497
39470
|
}
|
|
38498
|
-
|
|
38499
|
-
ctx
|
|
39471
|
+
const key = args[0] === "system" ? "contextBudget.systemPrompt" : "contextBudget.responseReserve";
|
|
39472
|
+
const result2 = await mutateConfig(ctx, key, raw);
|
|
39473
|
+
if (!result2.ok) {
|
|
39474
|
+
renderConfigError(ctx, result2);
|
|
39475
|
+
return;
|
|
39476
|
+
}
|
|
39477
|
+
ctx.output.writeLine(pc.green(t("cli.context_fraction_set", { key: args[0], value: result2.display })));
|
|
39478
|
+
return;
|
|
39479
|
+
}
|
|
39480
|
+
if (!/^\d+$/.test(args[0])) {
|
|
39481
|
+
ctx.output.writeLine(pc.yellow(t("context.unknown_arg", { arg: args[0] })));
|
|
39482
|
+
ctx.output.writeLine(t("repl.context_usage"));
|
|
38500
39483
|
return;
|
|
38501
39484
|
}
|
|
38502
|
-
const
|
|
38503
|
-
if (
|
|
38504
|
-
ctx
|
|
39485
|
+
const result = await mutateConfig(ctx, "contextWindow", args[0]);
|
|
39486
|
+
if (!result.ok) {
|
|
39487
|
+
renderConfigError(ctx, result);
|
|
38505
39488
|
return;
|
|
38506
39489
|
}
|
|
38507
|
-
ctx.
|
|
38508
|
-
|
|
38509
|
-
ctx.output.writeLine(pc.green(t("cli.context_set", { size })));
|
|
39490
|
+
ctx.output.writeLine(pc.green(t("cli.context_set", { size: String(result.value) })));
|
|
39491
|
+
reportSaved(ctx, result);
|
|
38510
39492
|
}
|
|
38511
39493
|
});
|
|
38512
39494
|
}
|
|
@@ -38565,15 +39547,15 @@ function registerLspCommands(ctx) {
|
|
|
38565
39547
|
name: "lsp",
|
|
38566
39548
|
description: t("repl.lsp"),
|
|
38567
39549
|
usage: t("repl.lsp_usage"),
|
|
39550
|
+
examples: ["/lsp status", "/lsp restart", "/lsp check src/index.ts"],
|
|
38568
39551
|
action: async (args) => {
|
|
38569
|
-
const subcommand = args[0] || "status";
|
|
38570
39552
|
const lspModule = ctx.agent.getModule("lsp");
|
|
38571
39553
|
if (!lspModule) {
|
|
38572
39554
|
ctx.output.writeLine(pc.yellow(t("repl.lsp_not_available")));
|
|
38573
39555
|
return;
|
|
38574
39556
|
}
|
|
38575
|
-
|
|
38576
|
-
|
|
39557
|
+
const handlers = {
|
|
39558
|
+
status: () => {
|
|
38577
39559
|
const disabled = lspModule.getDisabledServers();
|
|
38578
39560
|
const failures = lspModule.getFailureCounts();
|
|
38579
39561
|
const config = ctx.config.lsp;
|
|
@@ -38591,16 +39573,14 @@ function registerLspCommands(ctx) {
|
|
|
38591
39573
|
if (disabled.length === 0 && failures.size === 0) {
|
|
38592
39574
|
ctx.output.writeLine(pc.green(t("repl.lsp_all_ok")));
|
|
38593
39575
|
}
|
|
38594
|
-
|
|
38595
|
-
|
|
38596
|
-
case "restart": {
|
|
39576
|
+
},
|
|
39577
|
+
restart: () => {
|
|
38597
39578
|
ctx.output.writeLine(pc.yellow(t("repl.lsp_restarting")));
|
|
38598
39579
|
lspModule.resetDisabledServers();
|
|
38599
39580
|
ctx.output.writeLine(pc.green(t("repl.lsp_restarted")));
|
|
38600
|
-
|
|
38601
|
-
|
|
38602
|
-
|
|
38603
|
-
const path = args[1];
|
|
39581
|
+
},
|
|
39582
|
+
check: async (rest) => {
|
|
39583
|
+
const path = rest[0];
|
|
38604
39584
|
if (!path) {
|
|
38605
39585
|
ctx.output.writeLine(pc.yellow(t("repl.lsp_check_usage")));
|
|
38606
39586
|
return;
|
|
@@ -38614,13 +39594,16 @@ function registerLspCommands(ctx) {
|
|
|
38614
39594
|
} catch (e) {
|
|
38615
39595
|
ctx.output.writeLine(pc.red(t("repl.lsp_check_error", { error: errMsg(e) })), "stderr");
|
|
38616
39596
|
}
|
|
38617
|
-
break;
|
|
38618
|
-
}
|
|
38619
|
-
default: {
|
|
38620
|
-
ctx.output.writeLine(pc.dim(t("repl.lsp_usage")));
|
|
38621
|
-
break;
|
|
38622
39597
|
}
|
|
39598
|
+
};
|
|
39599
|
+
const subcommand = args[0] || "status";
|
|
39600
|
+
const handler = handlers[subcommand];
|
|
39601
|
+
if (!handler) {
|
|
39602
|
+
ctx.output.writeLine(pc.yellow(t("repl.unknown_sub", { cmd: "lsp", sub: subcommand })));
|
|
39603
|
+
ctx.output.writeLine(pc.dim(t("repl.lsp_usage")));
|
|
39604
|
+
return;
|
|
38623
39605
|
}
|
|
39606
|
+
await handler(args.slice(1));
|
|
38624
39607
|
}
|
|
38625
39608
|
});
|
|
38626
39609
|
}
|
|
@@ -38684,8 +39667,9 @@ function registerSessionCommands(ctx) {
|
|
|
38684
39667
|
ctx.registerCommand({
|
|
38685
39668
|
name: "resume",
|
|
38686
39669
|
description: t("repl.resume"),
|
|
38687
|
-
aliases: ["switch"
|
|
39670
|
+
aliases: ["switch"],
|
|
38688
39671
|
usage: t("repl.resume_usage"),
|
|
39672
|
+
examples: ["/resume", "/resume my-session"],
|
|
38689
39673
|
action: (args) => {
|
|
38690
39674
|
const query = args.join(" ");
|
|
38691
39675
|
const sessions = ctx.sessionManager.list();
|
|
@@ -38772,6 +39756,77 @@ function registerSessionCommands(ctx) {
|
|
|
38772
39756
|
ctx.output.writeLine(`${t("session.deleted", { id: match.id })}: ${match.name}`);
|
|
38773
39757
|
}
|
|
38774
39758
|
});
|
|
39759
|
+
ctx.registerCommand({
|
|
39760
|
+
name: "export",
|
|
39761
|
+
description: t("repl.export"),
|
|
39762
|
+
usage: t("repl.export_usage"),
|
|
39763
|
+
examples: [
|
|
39764
|
+
"/export",
|
|
39765
|
+
"/export my-session --format md",
|
|
39766
|
+
"/export --format json --out -"
|
|
39767
|
+
],
|
|
39768
|
+
action: async (args) => {
|
|
39769
|
+
let format = "md";
|
|
39770
|
+
let out;
|
|
39771
|
+
let redact = true;
|
|
39772
|
+
const positional = [];
|
|
39773
|
+
for (let i = 0;i < args.length; i++) {
|
|
39774
|
+
const a = args[i];
|
|
39775
|
+
if (a === "--format") {
|
|
39776
|
+
const v = args[++i];
|
|
39777
|
+
if (!v) {
|
|
39778
|
+
ctx.output.writeLine(t("export.missing_value", { flag: a }));
|
|
39779
|
+
return;
|
|
39780
|
+
}
|
|
39781
|
+
format = v;
|
|
39782
|
+
} else if (a === "--out") {
|
|
39783
|
+
const v = args[++i];
|
|
39784
|
+
if (v === undefined) {
|
|
39785
|
+
ctx.output.writeLine(t("export.missing_value", { flag: a }));
|
|
39786
|
+
return;
|
|
39787
|
+
}
|
|
39788
|
+
out = v;
|
|
39789
|
+
} else if (a === "--no-redact") {
|
|
39790
|
+
redact = false;
|
|
39791
|
+
} else {
|
|
39792
|
+
positional.push(a);
|
|
39793
|
+
}
|
|
39794
|
+
}
|
|
39795
|
+
if (format !== "md" && format !== "json" && format !== "jsonl") {
|
|
39796
|
+
ctx.output.writeLine(pc.yellow(t("export.invalid_format", { format })), "stderr");
|
|
39797
|
+
return;
|
|
39798
|
+
}
|
|
39799
|
+
const query = positional.join(" ");
|
|
39800
|
+
const sessions = ctx.sessionManager.list();
|
|
39801
|
+
const match = query ? sessions.find((s) => s.id === query || s.id.startsWith(query) || s.name.toLowerCase().includes(query.toLowerCase())) : sessions.find((s) => s.id === ctx.sessionManager.getActive());
|
|
39802
|
+
if (!match) {
|
|
39803
|
+
ctx.output.writeLine(query ? t("session.no_match", { query }) : t("session.no_active"));
|
|
39804
|
+
return;
|
|
39805
|
+
}
|
|
39806
|
+
const messages = ctx.sessionManager.getHistory(match.id);
|
|
39807
|
+
const log2 = ctx.sessionManager.loadSessionLog(match.id);
|
|
39808
|
+
if (format === "jsonl" ? log2.length === 0 : messages.length === 0) {
|
|
39809
|
+
ctx.output.writeLine(pc.yellow(t("export.empty")));
|
|
39810
|
+
return;
|
|
39811
|
+
}
|
|
39812
|
+
const text = redactExport(formatExport({ meta: match, messages, log: log2 }, format), redact);
|
|
39813
|
+
if (out === "-") {
|
|
39814
|
+
ctx.output.writeLine(text);
|
|
39815
|
+
return;
|
|
39816
|
+
}
|
|
39817
|
+
const baseDir = out ? dirname25(out) : join55(homedir18(), ".mma", "exports");
|
|
39818
|
+
const path = out ?? join55(baseDir, `${sanitizeFileName(match.name)}-${match.id.slice(0, 8)}.${extensionFor(format)}`);
|
|
39819
|
+
try {
|
|
39820
|
+
mkdirSync26(baseDir, { recursive: true });
|
|
39821
|
+
writeFileSync25(path, text, "utf-8");
|
|
39822
|
+
} catch (e) {
|
|
39823
|
+
ctx.output.writeLine(pc.red(t("export.write_failed", { error: errMsg(e) })), "stderr");
|
|
39824
|
+
return;
|
|
39825
|
+
}
|
|
39826
|
+
ctx.output.writeLine(pc.green(t("export.written", { path })));
|
|
39827
|
+
ctx.output.writeLine(pc.dim(redact ? t("export.redacted") : t("export.raw")));
|
|
39828
|
+
}
|
|
39829
|
+
});
|
|
38775
39830
|
}
|
|
38776
39831
|
function registerSkillCommands(ctx) {
|
|
38777
39832
|
if (!ctx.skillsModule)
|
|
@@ -38862,7 +39917,7 @@ function registerSkillCommands(ctx) {
|
|
|
38862
39917
|
const subcmd = args[0];
|
|
38863
39918
|
const handler = subcmd ? skillHandlers[subcmd] : skillHandlers.list;
|
|
38864
39919
|
if (!handler) {
|
|
38865
|
-
ctx.output.writeLine(pc.
|
|
39920
|
+
ctx.output.writeLine(pc.yellow(t("repl.unknown_sub", { cmd: "skill", sub: subcmd })));
|
|
38866
39921
|
ctx.output.writeLine(t("repl.skill_usage"));
|
|
38867
39922
|
return;
|
|
38868
39923
|
}
|
|
@@ -38891,9 +39946,10 @@ async function runConfigMigrate(ctx) {
|
|
|
38891
39946
|
const domainFiles = readdirSync20(join55(configDir, "config")).filter((f) => f.endsWith(".json"));
|
|
38892
39947
|
ctx.output.writeLine(pc.green(t("config.migrate_done", { count: String(domainFiles.length) })));
|
|
38893
39948
|
}
|
|
38894
|
-
var version2, COMMAND_GROUPS;
|
|
39949
|
+
var version2, COMMAND_GROUPS, SUGAR_HINTS;
|
|
38895
39950
|
var init_repl_commands = __esm(() => {
|
|
38896
39951
|
init_colors();
|
|
39952
|
+
init_theme();
|
|
38897
39953
|
init_version();
|
|
38898
39954
|
init_table();
|
|
38899
39955
|
init_i18n();
|
|
@@ -38902,6 +39958,8 @@ var init_repl_commands = __esm(() => {
|
|
|
38902
39958
|
init_config2();
|
|
38903
39959
|
init_presets();
|
|
38904
39960
|
init_budget();
|
|
39961
|
+
init_registry2();
|
|
39962
|
+
init_export();
|
|
38905
39963
|
init_token_counter();
|
|
38906
39964
|
init_map_command();
|
|
38907
39965
|
init_utils();
|
|
@@ -38929,9 +39987,20 @@ var init_repl_commands = __esm(() => {
|
|
|
38929
39987
|
resume: "session",
|
|
38930
39988
|
rename: "session",
|
|
38931
39989
|
delete: "session",
|
|
39990
|
+
export: "session",
|
|
38932
39991
|
skill: "skill",
|
|
38933
39992
|
plugins: "agent"
|
|
38934
39993
|
};
|
|
39994
|
+
SUGAR_HINTS = {
|
|
39995
|
+
model: "/model use <name>",
|
|
39996
|
+
"provider.active": "/provider use <name>",
|
|
39997
|
+
contextWindow: "/context <size>",
|
|
39998
|
+
"contextBudget.systemPrompt": "/context system <share>",
|
|
39999
|
+
"contextBudget.responseReserve": "/context reserve <share>",
|
|
40000
|
+
showReasoning: "/reasoning show | hide",
|
|
40001
|
+
"reasoning.mode": "/reasoning level <level>",
|
|
40002
|
+
"ui.verbosity": "/verbose <level>"
|
|
40003
|
+
};
|
|
38935
40004
|
});
|
|
38936
40005
|
|
|
38937
40006
|
// node_modules/commander/esm.mjs
|
|
@@ -38957,9 +40026,10 @@ init_setup();
|
|
|
38957
40026
|
init_setup_order();
|
|
38958
40027
|
init_i18n();
|
|
38959
40028
|
init_colors();
|
|
40029
|
+
init_export();
|
|
38960
40030
|
import { join as join53, dirname as dirname24 } from "path";
|
|
38961
40031
|
import { homedir as homedir17 } from "os";
|
|
38962
|
-
import { existsSync as existsSync59 } from "fs";
|
|
40032
|
+
import { existsSync as existsSync59, mkdirSync as mkdirSync25, writeFileSync as writeFileSync24 } from "fs";
|
|
38963
40033
|
|
|
38964
40034
|
// src/cli/security-commands.ts
|
|
38965
40035
|
init_bootstrap();
|
|
@@ -40224,6 +41294,41 @@ function buildSessionCommands(program2) {
|
|
|
40224
41294
|
}
|
|
40225
41295
|
}
|
|
40226
41296
|
});
|
|
41297
|
+
session2.command("export").argument("<id>", "Session id (or name prefix)").description(t("cli.export_session")).option("--format <format>", t("cli.export_format"), "md").option("--out <path>", t("cli.export_out")).option("--no-redact", t("cli.export_no_redact")).action(async (id, opts) => {
|
|
41298
|
+
const { sessionManager } = await bootstrap();
|
|
41299
|
+
const meta = sessionManager.get(id) ?? sessionManager.list().find((s) => s.id.startsWith(id)) ?? sessionManager.list().find((s) => s.name.toLowerCase().includes(id.toLowerCase()));
|
|
41300
|
+
if (!meta) {
|
|
41301
|
+
getDefaultChannel().writeLine(t("session.not_found", { id }));
|
|
41302
|
+
return;
|
|
41303
|
+
}
|
|
41304
|
+
const format = opts.format;
|
|
41305
|
+
if (format !== "md" && format !== "json" && format !== "jsonl") {
|
|
41306
|
+
getDefaultChannel().writeLine(t("export.invalid_format", { format }));
|
|
41307
|
+
return;
|
|
41308
|
+
}
|
|
41309
|
+
const messages = sessionManager.getHistory(meta.id);
|
|
41310
|
+
const log2 = sessionManager.loadSessionLog(meta.id);
|
|
41311
|
+
if (format === "jsonl" ? log2.length === 0 : messages.length === 0) {
|
|
41312
|
+
getDefaultChannel().writeLine(t("export.empty"));
|
|
41313
|
+
return;
|
|
41314
|
+
}
|
|
41315
|
+
const text = redactExport(formatExport({ meta, messages, log: log2 }, format), opts.redact);
|
|
41316
|
+
if (opts.out === "-") {
|
|
41317
|
+
getDefaultChannel().writeLine(text);
|
|
41318
|
+
return;
|
|
41319
|
+
}
|
|
41320
|
+
const baseDir = opts.out ? dirname24(opts.out) : join53(homedir17(), ".mma", "exports");
|
|
41321
|
+
const path = opts.out ?? join53(baseDir, `${sanitizeFileName(meta.name)}-${meta.id.slice(0, 8)}.${extensionFor(format)}`);
|
|
41322
|
+
try {
|
|
41323
|
+
mkdirSync25(baseDir, { recursive: true });
|
|
41324
|
+
writeFileSync24(path, text, "utf-8");
|
|
41325
|
+
} catch (e) {
|
|
41326
|
+
getDefaultChannel().writeLine(t("export.write_failed", { error: String(e) }));
|
|
41327
|
+
return;
|
|
41328
|
+
}
|
|
41329
|
+
getDefaultChannel().writeLine(t("export.written", { path }));
|
|
41330
|
+
getDefaultChannel().writeLine(t(opts.redact ? "export.redacted" : "export.raw"));
|
|
41331
|
+
});
|
|
40227
41332
|
session2.command("delete").argument("<id>", "Session id").description(t("cli.delete_session")).action(async (id) => {
|
|
40228
41333
|
const { sessionManager } = await bootstrap();
|
|
40229
41334
|
sessionManager.delete(id);
|
|
@@ -41355,11 +42460,13 @@ class LineEditor {
|
|
|
41355
42460
|
}
|
|
41356
42461
|
|
|
41357
42462
|
// src/cli/repl.ts
|
|
41358
|
-
import { existsSync as existsSync61, mkdirSync as
|
|
42463
|
+
import { existsSync as existsSync61, mkdirSync as mkdirSync27, readFileSync as readFileSync42, writeFileSync as writeFileSync26 } from "fs";
|
|
41359
42464
|
import { dirname as dirname26, join as join56 } from "path";
|
|
41360
|
-
import { homedir as
|
|
42465
|
+
import { homedir as homedir19 } from "os";
|
|
41361
42466
|
|
|
41362
42467
|
// src/cli/completer.ts
|
|
42468
|
+
init_registry2();
|
|
42469
|
+
init_i18n();
|
|
41363
42470
|
import { readdirSync as readdirSync19, statSync as statSync11 } from "fs";
|
|
41364
42471
|
import { join as join54 } from "path";
|
|
41365
42472
|
function buildSlashCompletions(commands) {
|
|
@@ -41464,11 +42571,13 @@ class ProviderArgProvider {
|
|
|
41464
42571
|
class SessionNameProvider {
|
|
41465
42572
|
name = "session-names";
|
|
41466
42573
|
getNames;
|
|
41467
|
-
|
|
42574
|
+
commands;
|
|
42575
|
+
constructor(getNames, commands = ["/resume"]) {
|
|
41468
42576
|
this.getNames = getNames;
|
|
42577
|
+
this.commands = commands;
|
|
41469
42578
|
}
|
|
41470
42579
|
match(ctx) {
|
|
41471
|
-
return ctx.tokenIndex >= 1 && ctx.tokens[0]
|
|
42580
|
+
return ctx.tokenIndex >= 1 && this.commands.includes(ctx.tokens[0]);
|
|
41472
42581
|
}
|
|
41473
42582
|
complete(ctx) {
|
|
41474
42583
|
const names = this.getNames();
|
|
@@ -41500,6 +42609,74 @@ class SkillNameProvider {
|
|
|
41500
42609
|
}
|
|
41501
42610
|
}
|
|
41502
42611
|
|
|
42612
|
+
class ConfigKeyProvider {
|
|
42613
|
+
name = "config-keys";
|
|
42614
|
+
match(ctx) {
|
|
42615
|
+
return ctx.tokenIndex === 1 && ctx.tokens[0] === "/config";
|
|
42616
|
+
}
|
|
42617
|
+
complete(ctx) {
|
|
42618
|
+
const partial = ctx.partial;
|
|
42619
|
+
const items = allConfigNames().map(({ name, def, alias }) => ({
|
|
42620
|
+
value: name,
|
|
42621
|
+
description: alias ? `${t("config.alias_label")} ${def.key}` : def.domain
|
|
42622
|
+
}));
|
|
42623
|
+
if (!partial.includes(".")) {
|
|
42624
|
+
const groups = [...new Set(canonicalKeys().filter((k) => k.includes(".")).map((k) => k.split(".")[0]))];
|
|
42625
|
+
const groupItems = groups.map((g) => ({
|
|
42626
|
+
value: g,
|
|
42627
|
+
description: t("config.group_label")
|
|
42628
|
+
}));
|
|
42629
|
+
return [...groupItems, ...items].filter((i) => i.value.startsWith(partial));
|
|
42630
|
+
}
|
|
42631
|
+
return items.filter((i) => i.value.startsWith(partial));
|
|
42632
|
+
}
|
|
42633
|
+
}
|
|
42634
|
+
|
|
42635
|
+
class ConfigValueProvider {
|
|
42636
|
+
name = "config-values";
|
|
42637
|
+
match(ctx) {
|
|
42638
|
+
return ctx.tokenIndex === 2 && ctx.tokens[0] === "/config";
|
|
42639
|
+
}
|
|
42640
|
+
complete(ctx) {
|
|
42641
|
+
const def = resolveConfigKey(ctx.tokens[1]);
|
|
42642
|
+
if (!def?.enumValues)
|
|
42643
|
+
return [];
|
|
42644
|
+
return def.enumValues.filter((v) => v.startsWith(ctx.partial)).map((v) => ({ value: v }));
|
|
42645
|
+
}
|
|
42646
|
+
}
|
|
42647
|
+
|
|
42648
|
+
class FlagProvider {
|
|
42649
|
+
name = "provider-add-flags";
|
|
42650
|
+
match(ctx) {
|
|
42651
|
+
return ctx.tokens[0] === "/provider" && ctx.tokens[1] === "add" && ctx.tokenIndex >= 2;
|
|
42652
|
+
}
|
|
42653
|
+
complete(ctx) {
|
|
42654
|
+
const flags = [
|
|
42655
|
+
{ value: "--url", description: t("repl.provider_flag_url") },
|
|
42656
|
+
{ value: "--key", description: t("repl.provider_flag_key") },
|
|
42657
|
+
{ value: "--priority", description: t("repl.provider_flag_priority") },
|
|
42658
|
+
{ value: "--context-window", description: t("repl.provider_flag_context_window") },
|
|
42659
|
+
{ value: "--rpm", description: t("repl.provider_flag_rpm") },
|
|
42660
|
+
{ value: "--parallel", description: t("repl.provider_flag_parallel") }
|
|
42661
|
+
];
|
|
42662
|
+
return flags.filter((f) => f.value.startsWith(ctx.partial));
|
|
42663
|
+
}
|
|
42664
|
+
}
|
|
42665
|
+
|
|
42666
|
+
class CommandArgProvider {
|
|
42667
|
+
name = "help-command-args";
|
|
42668
|
+
getNames;
|
|
42669
|
+
constructor(getNames) {
|
|
42670
|
+
this.getNames = getNames;
|
|
42671
|
+
}
|
|
42672
|
+
match(ctx) {
|
|
42673
|
+
return ctx.tokenIndex === 1 && ctx.tokens[0] === "/help";
|
|
42674
|
+
}
|
|
42675
|
+
complete(ctx) {
|
|
42676
|
+
return this.getNames().filter((n) => n.startsWith(ctx.partial)).map((n) => ({ value: n }));
|
|
42677
|
+
}
|
|
42678
|
+
}
|
|
42679
|
+
|
|
41503
42680
|
class Completer {
|
|
41504
42681
|
providers = [];
|
|
41505
42682
|
registerProvider(provider) {
|
|
@@ -41534,109 +42711,7 @@ init_colors();
|
|
|
41534
42711
|
init_string_width();
|
|
41535
42712
|
init_i18n();
|
|
41536
42713
|
init_table();
|
|
41537
|
-
|
|
41538
|
-
// src/ui/theme.ts
|
|
41539
|
-
init_colors();
|
|
41540
|
-
var glyph = {
|
|
41541
|
-
action: "◇",
|
|
41542
|
-
success: "✓",
|
|
41543
|
-
failure: "✗",
|
|
41544
|
-
warning: "⚠",
|
|
41545
|
-
thinking: "✦",
|
|
41546
|
-
question: "?",
|
|
41547
|
-
user: "↵",
|
|
41548
|
-
detail: "↳",
|
|
41549
|
-
group: "│",
|
|
41550
|
-
metric: "⟡",
|
|
41551
|
-
compact: "⟳"
|
|
41552
|
-
};
|
|
41553
|
-
function resolveVerbosity(ui) {
|
|
41554
|
-
if (ui?.verbosity)
|
|
41555
|
-
return ui.verbosity;
|
|
41556
|
-
return ui?.verbose ? "verbose" : "quiet";
|
|
41557
|
-
}
|
|
41558
|
-
var CATEGORY_TOOLS = {
|
|
41559
|
-
recon: new Set([
|
|
41560
|
-
"read_file",
|
|
41561
|
-
"list_dir",
|
|
41562
|
-
"glob",
|
|
41563
|
-
"grep",
|
|
41564
|
-
"file_info",
|
|
41565
|
-
"project_map",
|
|
41566
|
-
"chunk_query",
|
|
41567
|
-
"web_search",
|
|
41568
|
-
"web_fetch",
|
|
41569
|
-
"web_browse",
|
|
41570
|
-
"search_history",
|
|
41571
|
-
"recall",
|
|
41572
|
-
"session_info",
|
|
41573
|
-
"process_list",
|
|
41574
|
-
"process_log"
|
|
41575
|
-
]),
|
|
41576
|
-
mutate: new Set([
|
|
41577
|
-
"write_file",
|
|
41578
|
-
"edit_file",
|
|
41579
|
-
"create_dir",
|
|
41580
|
-
"delete_file",
|
|
41581
|
-
"move_file",
|
|
41582
|
-
"attach_image"
|
|
41583
|
-
]),
|
|
41584
|
-
execute: new Set([
|
|
41585
|
-
"bash",
|
|
41586
|
-
"process_kill",
|
|
41587
|
-
"pipeline_run",
|
|
41588
|
-
"browser",
|
|
41589
|
-
"download_file",
|
|
41590
|
-
"subagent",
|
|
41591
|
-
"mcp_call"
|
|
41592
|
-
]),
|
|
41593
|
-
meta: new Set([
|
|
41594
|
-
"plan",
|
|
41595
|
-
"todo",
|
|
41596
|
-
"verify",
|
|
41597
|
-
"lsp_check",
|
|
41598
|
-
"enable_tools",
|
|
41599
|
-
"set_thinking",
|
|
41600
|
-
"load_skill",
|
|
41601
|
-
"remember"
|
|
41602
|
-
])
|
|
41603
|
-
};
|
|
41604
|
-
function toolCategory(tool) {
|
|
41605
|
-
for (const [category, tools] of Object.entries(CATEGORY_TOOLS)) {
|
|
41606
|
-
if (tools.has(tool))
|
|
41607
|
-
return category;
|
|
41608
|
-
}
|
|
41609
|
-
return "meta";
|
|
41610
|
-
}
|
|
41611
|
-
function toolAccent(tool) {
|
|
41612
|
-
switch (toolCategory(tool)) {
|
|
41613
|
-
case "recon":
|
|
41614
|
-
return pc.cyan;
|
|
41615
|
-
case "mutate":
|
|
41616
|
-
return pc.magenta;
|
|
41617
|
-
case "execute":
|
|
41618
|
-
return pc.blue;
|
|
41619
|
-
case "meta":
|
|
41620
|
-
default:
|
|
41621
|
-
return pc.dim;
|
|
41622
|
-
}
|
|
41623
|
-
}
|
|
41624
|
-
function actionMarkFor(tool) {
|
|
41625
|
-
return toolAccent(tool)(glyph.action);
|
|
41626
|
-
}
|
|
41627
|
-
function successMark() {
|
|
41628
|
-
return pc.green(glyph.success);
|
|
41629
|
-
}
|
|
41630
|
-
function failureMark() {
|
|
41631
|
-
return pc.red(glyph.failure);
|
|
41632
|
-
}
|
|
41633
|
-
function formatDuration(ms) {
|
|
41634
|
-
if (ms < 1000)
|
|
41635
|
-
return `${ms}ms`;
|
|
41636
|
-
return `${(ms / 1000).toFixed(1)}s`;
|
|
41637
|
-
}
|
|
41638
|
-
|
|
41639
|
-
// src/ui/md-formatter.ts
|
|
42714
|
+
init_theme();
|
|
41640
42715
|
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;
|
|
41641
42716
|
var STRING = /('[^']*'|"[^"]*"|`[^`]*`)/g;
|
|
41642
42717
|
var COMMENT = /(\/\/[^\n]*|\/\*[\s\S]*?\*\/|#[^\n]*)/g;
|
|
@@ -41892,6 +42967,7 @@ function formatWarning(text) {
|
|
|
41892
42967
|
|
|
41893
42968
|
// src/ui/renderer.ts
|
|
41894
42969
|
init_spinner();
|
|
42970
|
+
init_theme();
|
|
41895
42971
|
|
|
41896
42972
|
// src/ui/action-log.ts
|
|
41897
42973
|
var last = null;
|
|
@@ -42359,9 +43435,11 @@ ${pc.dim(glyph.metric)} ${model} · ${provider} · ${pc.dim(formatDuration(durat
|
|
|
42359
43435
|
}
|
|
42360
43436
|
|
|
42361
43437
|
// src/cli/repl.ts
|
|
43438
|
+
init_theme();
|
|
42362
43439
|
init_box();
|
|
42363
43440
|
init_i18n();
|
|
42364
43441
|
init_repl_commands();
|
|
43442
|
+
init_registry2();
|
|
42365
43443
|
|
|
42366
43444
|
// src/modules/lsp/probe.ts
|
|
42367
43445
|
init_client2();
|
|
@@ -42445,6 +43523,7 @@ init_session_logger();
|
|
|
42445
43523
|
|
|
42446
43524
|
// src/ui/plan-view.ts
|
|
42447
43525
|
init_colors();
|
|
43526
|
+
init_theme();
|
|
42448
43527
|
init_js_identifiers();
|
|
42449
43528
|
init_i18n();
|
|
42450
43529
|
function currentStepIndex(plan) {
|
|
@@ -42647,6 +43726,7 @@ function createHostBridge(opts) {
|
|
|
42647
43726
|
class Repl {
|
|
42648
43727
|
completer = new Completer;
|
|
42649
43728
|
modelCache = [];
|
|
43729
|
+
configSnapshot = new Map;
|
|
42650
43730
|
running = false;
|
|
42651
43731
|
agentRunning = false;
|
|
42652
43732
|
inputLocked = false;
|
|
@@ -42690,10 +43770,10 @@ class Repl {
|
|
|
42690
43770
|
this.execModule = execModule;
|
|
42691
43771
|
this.slog = new SessionLogger(sessionManager, logger4);
|
|
42692
43772
|
this.bindSessionOutput();
|
|
42693
|
-
this.configDir = configDir || join56(
|
|
43773
|
+
this.configDir = configDir || join56(homedir19(), ".mma");
|
|
42694
43774
|
this.baseDir = baseDir || process.cwd();
|
|
42695
43775
|
this.noAgentsMd = noAgentsMd === true;
|
|
42696
|
-
this.historyPath = historyPath ?? join56(
|
|
43776
|
+
this.historyPath = historyPath ?? join56(homedir19(), ".mma", "repl-history");
|
|
42697
43777
|
this.loadHistory();
|
|
42698
43778
|
const editorCompleter = (line) => {
|
|
42699
43779
|
const [matches, partial] = this.completer.complete(line);
|
|
@@ -42747,6 +43827,7 @@ class Repl {
|
|
|
42747
43827
|
});
|
|
42748
43828
|
this.agent.setPromptIO?.(this.promptIO);
|
|
42749
43829
|
registerAllCommands(this);
|
|
43830
|
+
this.configSnapshot = captureConfigSnapshot(this.config);
|
|
42750
43831
|
this.setupCompleter();
|
|
42751
43832
|
this.setupListeners();
|
|
42752
43833
|
if (pluginManager) {
|
|
@@ -42807,9 +43888,9 @@ class Repl {
|
|
|
42807
43888
|
}
|
|
42808
43889
|
saveHistory() {
|
|
42809
43890
|
try {
|
|
42810
|
-
|
|
43891
|
+
mkdirSync27(dirname26(this.historyPath), { recursive: true });
|
|
42811
43892
|
const allHistory = this.history.slice(-this.maxHistory);
|
|
42812
|
-
|
|
43893
|
+
writeFileSync26(this.historyPath, allHistory.join(`
|
|
42813
43894
|
`), "utf-8");
|
|
42814
43895
|
} catch (e) {
|
|
42815
43896
|
this.logger?.debug(`Failed to save REPL history: ${e.message}`);
|
|
@@ -42820,14 +43901,59 @@ class Repl {
|
|
|
42820
43901
|
const slashCommands = buildSlashCompletions(this.commands);
|
|
42821
43902
|
this.completer.registerProvider(new SlashCommandProvider(slashCommands));
|
|
42822
43903
|
if (this.sessionManager) {
|
|
42823
|
-
this.completer.registerProvider(new SessionNameProvider(() => this.sessionManager.list().map((s) => s.name)
|
|
43904
|
+
this.completer.registerProvider(new SessionNameProvider(() => this.sessionManager.list().map((s) => s.name), [
|
|
43905
|
+
"/resume",
|
|
43906
|
+
"/delete",
|
|
43907
|
+
"/export"
|
|
43908
|
+
]));
|
|
42824
43909
|
}
|
|
42825
43910
|
if (this.skillsModule) {
|
|
42826
|
-
this.completer.registerProvider(new SubcommandProvider("skill", [
|
|
43911
|
+
this.completer.registerProvider(new SubcommandProvider("skill", [
|
|
43912
|
+
{ name: "list", description: t("skill.sub_list") },
|
|
43913
|
+
{ name: "loaded", description: t("skill.sub_loaded") },
|
|
43914
|
+
{ name: "load", description: t("skill.sub_load") },
|
|
43915
|
+
{ name: "unload", description: t("skill.sub_unload") },
|
|
43916
|
+
{ name: "search", description: t("skill.sub_search") }
|
|
43917
|
+
]));
|
|
42827
43918
|
this.completer.registerProvider(new SkillNameProvider(this.skillsModule));
|
|
42828
43919
|
}
|
|
42829
|
-
this.completer.registerProvider(new SubcommandProvider("provider", [
|
|
42830
|
-
|
|
43920
|
+
this.completer.registerProvider(new SubcommandProvider("provider", [
|
|
43921
|
+
{ name: "list", description: t("provider.sub_list") },
|
|
43922
|
+
{ name: "use", description: t("provider.sub_use") },
|
|
43923
|
+
{ name: "add", description: t("provider.sub_add") }
|
|
43924
|
+
]));
|
|
43925
|
+
this.completer.registerProvider(new SubcommandProvider("model", [
|
|
43926
|
+
{ name: "list", description: t("model.sub_list") },
|
|
43927
|
+
{ name: "use", description: t("model.sub_use") }
|
|
43928
|
+
]));
|
|
43929
|
+
this.completer.registerProvider(new SubcommandProvider("map", [
|
|
43930
|
+
{ name: "summary", description: t("map.sub_summary") },
|
|
43931
|
+
{ name: "refresh", description: t("map.sub_refresh") },
|
|
43932
|
+
{ name: "find", description: t("map.sub_find") }
|
|
43933
|
+
]));
|
|
43934
|
+
this.completer.registerProvider(new SubcommandProvider("context", [
|
|
43935
|
+
{ name: "system", description: t("context.sub_system") },
|
|
43936
|
+
{ name: "reserve", description: t("context.sub_reserve") }
|
|
43937
|
+
]));
|
|
43938
|
+
this.completer.registerProvider(new SubcommandProvider("lsp", [
|
|
43939
|
+
{ name: "status", description: t("lsp.sub_status") },
|
|
43940
|
+
{ name: "restart", description: t("lsp.sub_restart") },
|
|
43941
|
+
{ name: "check", description: t("lsp.sub_check") }
|
|
43942
|
+
]));
|
|
43943
|
+
this.completer.registerProvider(new SubcommandProvider("reasoning", [
|
|
43944
|
+
{ name: "show", description: t("reasoning.sub_show") },
|
|
43945
|
+
{ name: "hide", description: t("reasoning.sub_hide") },
|
|
43946
|
+
{ name: "level", description: t("reasoning.sub_level") }
|
|
43947
|
+
]));
|
|
43948
|
+
this.completer.registerProvider(new SubcommandProvider("verbose", [
|
|
43949
|
+
{ name: "quiet", description: t("verbose.sub_quiet") },
|
|
43950
|
+
{ name: "normal", description: t("verbose.sub_normal") },
|
|
43951
|
+
{ name: "verbose", description: t("verbose.sub_verbose") }
|
|
43952
|
+
]));
|
|
43953
|
+
this.completer.registerProvider(new ConfigKeyProvider);
|
|
43954
|
+
this.completer.registerProvider(new ConfigValueProvider);
|
|
43955
|
+
this.completer.registerProvider(new FlagProvider);
|
|
43956
|
+
this.completer.registerProvider(new CommandArgProvider(() => Array.from(this.commands.entries()).filter(([key, cmd]) => key === cmd.name).map(([, cmd]) => cmd.name)));
|
|
42831
43957
|
const entryLabels = this.config.provider?.entries?.map((e) => e.label || e.type) ?? [];
|
|
42832
43958
|
if (entryLabels.length > 0) {
|
|
42833
43959
|
this.completer.registerProvider(new ProviderArgProvider(entryLabels));
|
|
@@ -42836,6 +43962,17 @@ class Repl {
|
|
|
42836
43962
|
this.completer.registerProvider(new FilePathProvider(this.baseDir));
|
|
42837
43963
|
this.refreshModelCache();
|
|
42838
43964
|
}
|
|
43965
|
+
reregisterCommands() {
|
|
43966
|
+
this.commands.clear();
|
|
43967
|
+
registerAllCommands(this);
|
|
43968
|
+
this.setupCompleter();
|
|
43969
|
+
}
|
|
43970
|
+
getConfigSnapshot() {
|
|
43971
|
+
return this.configSnapshot;
|
|
43972
|
+
}
|
|
43973
|
+
knownModels() {
|
|
43974
|
+
return this.modelCache;
|
|
43975
|
+
}
|
|
42839
43976
|
refreshModelCache() {
|
|
42840
43977
|
(async () => {
|
|
42841
43978
|
try {
|
|
@@ -43182,7 +44319,13 @@ ${divider()}`);
|
|
|
43182
44319
|
this.runHandledPrompt = false;
|
|
43183
44320
|
const cmd = this.commands.get(name);
|
|
43184
44321
|
if (!cmd) {
|
|
43185
|
-
|
|
44322
|
+
const formerAliases = { use: "resume" };
|
|
44323
|
+
const suggestion = formerAliases[name];
|
|
44324
|
+
if (suggestion) {
|
|
44325
|
+
this.output.writeLine(pc.red(t("cli.unknown_command", { input: `/${name}`, suggestion: `/${suggestion}` })));
|
|
44326
|
+
} else {
|
|
44327
|
+
this.output.writeLine(`${pc.red(t("cli.unknown_cmd", { name }))} ${t("cli.help_hint")}`);
|
|
44328
|
+
}
|
|
43186
44329
|
return;
|
|
43187
44330
|
}
|
|
43188
44331
|
try {
|
|
@@ -43193,8 +44336,29 @@ ${divider()}`);
|
|
|
43193
44336
|
})), "stderr");
|
|
43194
44337
|
}
|
|
43195
44338
|
}
|
|
43196
|
-
showHelp() {
|
|
44339
|
+
showHelp(command) {
|
|
43197
44340
|
const { COMMAND_GROUPS: COMMAND_GROUPS2 } = (init_repl_commands(), __toCommonJS(exports_repl_commands));
|
|
44341
|
+
if (command) {
|
|
44342
|
+
const name = command.replace(/^\//, "");
|
|
44343
|
+
const cmd = this.commands.get(name);
|
|
44344
|
+
if (!cmd) {
|
|
44345
|
+
this.output.writeLine(pc.red(t("repl.help_unknown", { name })));
|
|
44346
|
+
return;
|
|
44347
|
+
}
|
|
44348
|
+
this.output.writeLine(pc.bold(pc.cyan("/" + cmd.name)));
|
|
44349
|
+
this.output.writeLine(` ${cmd.description}`);
|
|
44350
|
+
if (cmd.usage)
|
|
44351
|
+
this.output.writeLine(` ${pc.dim(cmd.usage)}`);
|
|
44352
|
+
if (cmd.aliases?.length) {
|
|
44353
|
+
this.output.writeLine(pc.dim(` ${t("repl.help_aliases", { names: cmd.aliases.join(", ") })}`));
|
|
44354
|
+
}
|
|
44355
|
+
if (cmd.examples?.length) {
|
|
44356
|
+
this.output.writeLine(pc.dim(` ${t("repl.help_examples")}`));
|
|
44357
|
+
for (const ex of cmd.examples)
|
|
44358
|
+
this.output.writeLine(pc.dim(` ${ex}`));
|
|
44359
|
+
}
|
|
44360
|
+
return;
|
|
44361
|
+
}
|
|
43198
44362
|
const order = ["general", "agent", "session", "skill"];
|
|
43199
44363
|
const seen = new Set;
|
|
43200
44364
|
for (const groupKey of order) {
|
|
@@ -43405,6 +44569,9 @@ ${line}`);
|
|
|
43405
44569
|
}
|
|
43406
44570
|
}
|
|
43407
44571
|
|
|
44572
|
+
// src/cli/main.ts
|
|
44573
|
+
init_theme();
|
|
44574
|
+
|
|
43408
44575
|
// src/cli/run-result.ts
|
|
43409
44576
|
init_i18n();
|
|
43410
44577
|
init_colors();
|
|
@@ -43498,7 +44665,7 @@ init_i18n();
|
|
|
43498
44665
|
init_colors();
|
|
43499
44666
|
import { existsSync as existsSync62 } from "fs";
|
|
43500
44667
|
import { join as join58, dirname as dirname27 } from "path";
|
|
43501
|
-
import { homedir as
|
|
44668
|
+
import { homedir as homedir21 } from "os";
|
|
43502
44669
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
43503
44670
|
|
|
43504
44671
|
// src/modules/updater/index.ts
|
|
@@ -43618,10 +44785,10 @@ init_environment();
|
|
|
43618
44785
|
init_data_sanitizer();
|
|
43619
44786
|
init_i18n();
|
|
43620
44787
|
init_utils();
|
|
43621
|
-
import { appendFileSync as appendFileSync8, mkdirSync as
|
|
44788
|
+
import { appendFileSync as appendFileSync8, mkdirSync as mkdirSync28 } from "fs";
|
|
43622
44789
|
import { join as join57 } from "path";
|
|
43623
|
-
import { homedir as
|
|
43624
|
-
var CRASH_LOG_DIR = join57(
|
|
44790
|
+
import { homedir as homedir20 } from "os";
|
|
44791
|
+
var CRASH_LOG_DIR = join57(homedir20(), ".mma", "logs");
|
|
43625
44792
|
var CRASH_LOG_FILE = "crash.jsonl";
|
|
43626
44793
|
function formatCrashEntry(type2, err) {
|
|
43627
44794
|
const message = errMsg(err);
|
|
@@ -43631,12 +44798,12 @@ function formatCrashEntry(type2, err) {
|
|
|
43631
44798
|
type: type2,
|
|
43632
44799
|
message: sanitizeLogMessage(message),
|
|
43633
44800
|
stack: sanitizeLogMessage(stack),
|
|
43634
|
-
environment: collectEnvironment({ configDir:
|
|
44801
|
+
environment: collectEnvironment({ configDir: homedir20(), scanTools: false })
|
|
43635
44802
|
};
|
|
43636
44803
|
}
|
|
43637
44804
|
function writeCrashEntry(dir, entry) {
|
|
43638
44805
|
try {
|
|
43639
|
-
|
|
44806
|
+
mkdirSync28(dir, { recursive: true });
|
|
43640
44807
|
appendFileSync8(join57(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
|
|
43641
44808
|
`, "utf-8");
|
|
43642
44809
|
} catch {}
|
|
@@ -43765,7 +44932,7 @@ async function main() {
|
|
|
43765
44932
|
}
|
|
43766
44933
|
const jsonSink = jsonOpt ? new JsonOutputSink(defaultOutputBus) : undefined;
|
|
43767
44934
|
const prompt = program2.args.join(" ");
|
|
43768
|
-
const mmaDir = process.env.MMA_CONFIG_DIR || join58(
|
|
44935
|
+
const mmaDir = process.env.MMA_CONFIG_DIR || join58(homedir21(), ".mma");
|
|
43769
44936
|
const { hasDomainFiles: hasDomainFiles2 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
|
|
43770
44937
|
const virgin = !existsSync62(join58(mmaDir, "config.json")) && !hasDomainFiles2(mmaDir);
|
|
43771
44938
|
const { agent, config, baseDir, legacyDetected, contextProbe } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete, reasoningLevel, contextLog);
|
|
@@ -43853,7 +45020,7 @@ async function main() {
|
|
|
43853
45020
|
await updater?.waitForIdle();
|
|
43854
45021
|
process.exit(exitCode);
|
|
43855
45022
|
} else {
|
|
43856
|
-
const mmaDir = process.env.MMA_CONFIG_DIR || join58(
|
|
45023
|
+
const mmaDir = process.env.MMA_CONFIG_DIR || join58(homedir21(), ".mma");
|
|
43857
45024
|
const legacyConfigPath = join58(mmaDir, "config.json");
|
|
43858
45025
|
let hasAnyConfig = existsSync62(legacyConfigPath);
|
|
43859
45026
|
if (!hasAnyConfig) {
|