micro-models-agent 2.9.0 → 2.10.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/dist/main.js CHANGED
@@ -2789,7 +2789,9 @@ Fix the error and re-edit the file (a clean write clears the failure), or mark t
2789
2789
  "cli.manage_config": "Manage configuration",
2790
2790
  "cli.config_key": "Config key (e.g., model, provider.baseUrl)",
2791
2791
  "cli.set_value": "Set a config value",
2792
+ "cli.config_force": "Bypass validation and write the raw value as-is",
2792
2793
  "cli.set_done": "Set {key}={value}",
2794
+ "cli.config_invalid": "Invalid value for '{key}' ({reason}). Config not changed.",
2793
2795
  "cli.show_config": "Show the effective configuration (secrets redacted; use --show-secrets to reveal)",
2794
2796
  "cli.migrate_config": "Migrate legacy config.json to domain format",
2795
2797
  "cli.manage_models": "Manage models",
@@ -2989,6 +2991,7 @@ Available commands:`,
2989
2991
  "repl.last_action_none": "No recent action to show.",
2990
2992
  "repl.status": "Show a compact status line",
2991
2993
  "repl.status_usage": "Usage: /status",
2994
+ "repl.security": "Show security configuration (on/off per area)",
2992
2995
  "repl.plugins": "List loaded plugins",
2993
2996
  "repl.plugins_usage": "Usage: /plugins [--all]",
2994
2997
  "repl.sessions": "List all sessions (* active)",
@@ -3600,6 +3603,15 @@ Updated: {updatedAt}`,
3600
3603
  "config.enum.max": "max",
3601
3604
  "config.enum.en": "English",
3602
3605
  "config.enum.ru": "Russian",
3606
+ "config.enum.security_block": "security block",
3607
+ "config.enum.bash_command": "bash command",
3608
+ "config.enum.file_operation": "file operation",
3609
+ "config.enum.network_request": "network request",
3610
+ "config.enum.tool_call": "tool call",
3611
+ "config.enum.authentication": "authentication",
3612
+ "config.enum.configuration_change": "config change",
3613
+ "config.enum.session_start": "session start",
3614
+ "config.enum.session_end": "session end",
3603
3615
  "config.desc.model": "Model used for the main agent.",
3604
3616
  "config.desc.provider.active": "Which configured provider is used.",
3605
3617
  "config.desc.contextWindow": "Total context size in tokens (system prompt + history + reserve).",
@@ -3618,7 +3630,7 @@ Updated: {updatedAt}`,
3618
3630
  "config.desc.critic.timeoutMs": "Verifier call timeout (fail-open).",
3619
3631
  "config.desc.logLevel": "Diagnostic log verbosity.",
3620
3632
  "config.desc.locale": "Language of the interface and agent messages.",
3621
- "config.desc.version": "Installed MMA version (read-only).",
3633
+ "config.desc.version": "Installed MMA version.",
3622
3634
  "config.desc.security.enabled": "Master switch for the security module (path checks, content scans, limits).",
3623
3635
  "config.desc.security.paths.enabled": "Restrict file operations to the workspace and block paths outside it.",
3624
3636
  "config.desc.security.contentScan.enabled": "Scan file contents for dangerous patterns before writing.",
@@ -3630,12 +3642,99 @@ Updated: {updatedAt}`,
3630
3642
  "web.settings.context": "Context",
3631
3643
  "web.settings.reasoning": "Reasoning",
3632
3644
  "web.settings.agent": "Agent",
3645
+ "web.settings.network": "Network",
3646
+ "web.settings.browser": "Browser",
3647
+ "web.settings.sessions": "Sessions",
3633
3648
  "web.settings.ui": "UI & Theme",
3634
3649
  "web.settings.memory": "Memory",
3635
3650
  "web.settings.skills": "Skills",
3636
3651
  "web.settings.plugins": "Plugins · MCP",
3637
3652
  "web.settings.security": "Security",
3638
3653
  "web.settings.advanced": "Advanced",
3654
+ "web.settings.search_placeholder": "search settings",
3655
+ "web.settings.search_empty": "no matching setting",
3656
+ "web.settings.table_invalid": "fill the required fields first ({field})",
3657
+ "web.settings.sec.general.interface": "Interface",
3658
+ "web.settings.sec.general.agent": "Agent loop",
3659
+ "web.settings.sec.general.agent.desc": "How long and how persistently the agent works before it stops.",
3660
+ "web.settings.sec.general.provider": "Providers",
3661
+ "web.settings.sec.model.tuning": "Performance",
3662
+ "web.settings.sec.model.tuning.desc": "Token budget and how the model is loaded into memory.",
3663
+ "web.settings.sec.model.capabilities": "Capabilities",
3664
+ "web.settings.sec.model.capabilities.desc": "Manual overrides for vision/tools when probing a model gets it wrong.",
3665
+ "web.settings.sec.context.window": "Context window",
3666
+ "web.settings.sec.context.window.desc": "Total window and how it is split between the system prompt, the reply and history.",
3667
+ "web.settings.sec.context.compaction": "Compaction",
3668
+ "web.settings.sec.context.compaction.desc": "When old history is summarised to free space.",
3669
+ "web.settings.sec.context.instructions": "Instructions",
3670
+ "web.settings.sec.context.instructions.desc": "What happens when AGENTS.md or the project map is too large for the prompt.",
3671
+ "web.settings.sec.context.log": "Context log",
3672
+ "web.settings.sec.context.log.desc": "Write every prompt sent to the model to a diff file next to the session.",
3673
+ "web.settings.sec.reasoning.display": "Display",
3674
+ "web.settings.sec.reasoning.effort": "Effort",
3675
+ "web.settings.sec.reasoning.effort.desc": "Stop overrides the range — auto picks a level per step inside it.",
3676
+ "web.settings.sec.agent.moe": "Mixture of experts",
3677
+ "web.settings.sec.agent.moe.desc": "Split work into expert subtasks with a planner; slower but stronger on multi-step tasks.",
3678
+ "web.settings.sec.agent.critic": "Critic",
3679
+ "web.settings.sec.agent.critic.desc": "A second pass that reviews the agent's own work before it answers.",
3680
+ "web.settings.sec.agent.tools": "Tools & skills",
3681
+ "web.settings.sec.agent.tools.desc": "Which tools are visible up front and how much of the prompt skills may use.",
3682
+ "web.settings.sec.agent.subagent": "Sub-agents",
3683
+ "web.settings.sec.agent.subagent.desc": "How results from sub-agents come back and how they are parallelised.",
3684
+ "web.settings.sec.agent.hallucination": "Hallucination check",
3685
+ "web.settings.sec.agent.hallucination.desc": "Run a consistency pass on the reply before showing it.",
3686
+ "web.settings.sec.network.web": "Web search",
3687
+ "web.settings.sec.network.web.desc": "Master switch for the web_search tool.",
3688
+ "web.settings.sec.network.error": "Automatic error search",
3689
+ "web.settings.sec.network.error.desc": "Search the web when the same error repeats.",
3690
+ "web.settings.sec.browser.main": "Browser",
3691
+ "web.settings.sec.browser.limits": "Limits",
3692
+ "web.settings.sec.browser.limits.desc": "Caps that keep a page snapshot small enough for the context window.",
3693
+ "web.settings.sec.browser.viewport": "Viewport & timeouts",
3694
+ "web.settings.sec.sessions.main": "Sessions",
3695
+ "web.settings.sec.sessions.main.desc": "Saving, naming and how many past sessions are kept.",
3696
+ "web.settings.sec.sessions.isolation": "Isolation",
3697
+ "web.settings.sec.sessions.isolation.desc": "Keep plugins and temp files separate per session.",
3698
+ "web.settings.sec.ui.chat": "Chat output",
3699
+ "web.settings.sec.ui.chat.desc": "Status lines, progress and context meters in the chat feed.",
3700
+ "web.settings.sec.ui.theme": "Theme",
3701
+ "web.settings.sec.ui.theme.desc": "Colour scheme of this web UI. Stored in the browser, not in the config file.",
3702
+ "web.settings.sec.memory.add": "Add a note",
3703
+ "web.settings.memory_add_title": "new memory",
3704
+ "config.field.name": "name",
3705
+ "config.field.model": "model",
3706
+ "config.field.tool_tags": "tool tags",
3707
+ "config.field.max_attempts": "attempts",
3708
+ "config.field.description": "description",
3709
+ "config.field.input": "input $/1M",
3710
+ "config.field.output": "output $/1M",
3711
+ "config.field.cachedInput": "cached $/1M",
3712
+ "config.field.cacheWrite": "write $/1M",
3713
+ "config.field.vision": "vision",
3714
+ "config.field.tools": "tools",
3715
+ "web.settings.sec.security.switches": "Switches",
3716
+ "web.settings.sec.security.switches.desc": "Master switches per protection. Turning one off disables its whole group below.",
3717
+ "web.settings.sec.security.limits": "Limits",
3718
+ "web.settings.sec.security.limits.desc": "Depth, volume and rate caps for tool activity.",
3719
+ "web.settings.sec.security.bash": "Bash rules",
3720
+ "web.settings.sec.security.bash.desc": "Commands, flags and operators the bash tool refuses.",
3721
+ "web.settings.sec.security.paths": "Path rules",
3722
+ "web.settings.sec.security.paths.desc": "Glob patterns for paths that are denied or, if set, exclusively allowed.",
3723
+ "web.settings.sec.security.network": "Network rules",
3724
+ "web.settings.sec.security.network.desc": "Domains blocked or, if set, exclusively allowed.",
3725
+ "web.settings.sec.security.scan": "Content scan",
3726
+ "web.settings.sec.security.scan.desc": "Patterns searched in file contents before writing.",
3727
+ "web.settings.sec.security.audit": "Audit log",
3728
+ "web.settings.sec.security.audit.desc": "Send security events to a file or a webhook.",
3729
+ "web.settings.sec.security.encryption": "Session encryption",
3730
+ "web.settings.sec.security.encryption.desc": "Encrypt saved chat history and session log on disk.",
3731
+ "web.settings.sec.security.access": "Access",
3732
+ "web.settings.sec.advanced.diagnostics": "Diagnostics",
3733
+ "web.settings.sec.advanced.diagnostics.desc": "Log verbosity and the installed version.",
3734
+ "web.settings.sec.advanced.retry": "Retry",
3735
+ "web.settings.sec.advanced.retry.desc": "Backoff for failed or stalled provider requests.",
3736
+ "web.settings.sec.advanced.service": "Service",
3737
+ "web.settings.sec.advanced.service.desc": "Cost tracking, prices and the background update check.",
3639
3738
  "web.settings.add": "add",
3640
3739
  "web.settings.forget": "forget",
3641
3740
  "web.settings.search": "search",
@@ -3673,6 +3772,11 @@ Updated: {updatedAt}`,
3673
3772
  "web.settings.provider_priority": "priority",
3674
3773
  "web.settings.provider_rpm": "requests / min",
3675
3774
  "web.settings.provider_parallel": "max parallel",
3775
+ "web.settings.provider_max_tokens": "max completion tokens",
3776
+ "web.settings.provider_cache_mechanism": "cache mechanism",
3777
+ "web.settings.provider_cache_report": "cache report format",
3778
+ "web.settings.provider_cache_flags": "cache flags",
3779
+ "web.settings.provider_retry": "retry",
3676
3780
  "web.settings.provider_required": "type and base URL are required",
3677
3781
  "web.settings.provider_invalid": "invalid numeric value",
3678
3782
  "web.settings.provider_active_guard": "cannot delete the active provider — switch first",
@@ -3705,6 +3809,14 @@ Updated: {updatedAt}`,
3705
3809
  "web.settings.disabled": "disabled",
3706
3810
  "web.settings.mcp_servers": "mcp servers",
3707
3811
  "web.settings.no_mcp": "no MCP servers configured",
3812
+ "web.settings.mcp_add": "add MCP server",
3813
+ "web.settings.mcp_edit_title": "edit MCP server",
3814
+ "web.settings.mcp_required": "name plus command (stdio) or URL (sse/http) is required",
3815
+ "web.settings.mcp_invalid": "invalid value: timeout 1000–300000 ms, args/env/headers as JSON",
3816
+ "web.settings.lsp_servers": "LSP servers",
3817
+ "web.settings.no_lsp": "no LSP servers configured",
3818
+ "web.settings.lsp_note": "LSP changes are saved to config and take effect on the next run.",
3819
+ "web.settings.lsp_unavailable": "LSP unavailable",
3708
3820
  "web.settings.loading": "loading…",
3709
3821
  "web.input.placeholder": "message… (/ for commands)",
3710
3822
  "web.input.enter": "Enter — send",
@@ -3763,6 +3875,8 @@ Updated: {updatedAt}`,
3763
3875
  "web.command.reasoning": "reasoning display and level",
3764
3876
  "web.command.verbose": "set UI verbosity",
3765
3877
  "web.command.context": "show or set the context window",
3878
+ "web.command.security": "show security toggles or write a security key",
3879
+ "web.security.unknown_sub": "unknown subcommand: security {sub}",
3766
3880
  "web.command.session": "list or activate a session",
3767
3881
  "web.command.export": "export the active session to a file",
3768
3882
  "web.command.memory": "inspect or edit global memory",
@@ -3868,7 +3982,192 @@ Updated: {updatedAt}`,
3868
3982
  "web.setup.finish": "Finish setup",
3869
3983
  "web.setup.saving": "Saving…",
3870
3984
  "web.setup.saved_warning": "Saved with warnings: {warning}",
3871
- "web.setup.failed": "Setup failed. Check the values and try again."
3985
+ "web.setup.failed": "Setup failed. Check the values and try again.",
3986
+ "config.key.provider.fallback": "fallback providers",
3987
+ "config.desc.provider.fallback": "Fall back to the next provider entry when the active one fails.",
3988
+ "config.key.provider.maxCompletionTokens": "max completion tokens",
3989
+ "config.desc.provider.maxCompletionTokens": "Hard cap on completion tokens per request (512-128000).",
3990
+ "config.key.contextBudget.compactionThreshold": "compaction threshold",
3991
+ "config.desc.contextBudget.compactionThreshold": "History load share that allows periodic compaction (0.05-0.9).",
3992
+ "config.key.contextBudget.compactionMinLoad": "compaction min load",
3993
+ "config.desc.contextBudget.compactionMinLoad": "Minimum history load required before compaction may run (0.05-0.9).",
3994
+ "config.key.instructions.summarize": "summarize instructions",
3995
+ "config.desc.instructions.summarize": "Summarize oversized AGENTS.md/project-map blocks instead of truncating.",
3996
+ "config.key.contextLog.enabled": "context log",
3997
+ "config.desc.contextLog.enabled": "Write the LLM-bound context of every iteration to <session>/context.diff.",
3998
+ "config.key.contextLog.redact": "redact context log",
3999
+ "config.desc.contextLog.redact": "Redact recognizable secrets (tokens, keys) in the context log.",
4000
+ "config.key.reasoning.min": "min reasoning",
4001
+ "config.desc.reasoning.min": "Lower bound of the reasoning effort range.",
4002
+ "config.key.reasoning.max": "max reasoning",
4003
+ "config.desc.reasoning.max": "Upper bound of the reasoning effort range.",
4004
+ "config.key.reasoning.baseline": "baseline reasoning",
4005
+ "config.desc.reasoning.baseline": "Default reasoning effort used when the model gives no signal.",
4006
+ "config.key.reasoning.overrideCooldown": "reasoning override cooldown",
4007
+ "config.desc.reasoning.overrideCooldown": "Turns before a fresh reasoning override is accepted again (1-60).",
4008
+ "config.key.autoPlan": "auto-plan",
4009
+ "config.desc.autoPlan": "Let the agent draft a plan automatically for multi-step tasks.",
4010
+ "config.key.tools.enableOnDemand": "on-demand tools",
4011
+ "config.desc.tools.enableOnDemand": "Load narrow tool groups on demand instead of exposing all tools.",
4012
+ "config.key.session.autoSave": "auto-save session",
4013
+ "config.desc.session.autoSave": "Persist the session log after every turn.",
4014
+ "config.key.session.maxSessions": "max sessions",
4015
+ "config.desc.session.maxSessions": "How many recent sessions are kept on disk (1-500).",
4016
+ "config.key.session.isolateMemory": "isolate session memory",
4017
+ "config.desc.session.isolateMemory": "Keep session memory separate from the global one.",
4018
+ "config.key.session.autoName": "auto-name sessions",
4019
+ "config.desc.session.autoName": "Derive a session name from the first message (LLM-refined).",
4020
+ "config.key.sessionIsolation.enabled": "session isolation",
4021
+ "config.desc.sessionIsolation.enabled": "Master switch for per-session isolation (plugins, temp files).",
4022
+ "config.key.sessionIsolation.isolatePlugins": "isolate plugins",
4023
+ "config.desc.sessionIsolation.isolatePlugins": "Give each session its own plugin sandbox.",
4024
+ "config.key.sessionIsolation.isolateTempFiles": "isolate temp files",
4025
+ "config.desc.sessionIsolation.isolateTempFiles": "Give each session its own temp-file directory.",
4026
+ "config.key.ui.spinner": "spinner",
4027
+ "config.desc.ui.spinner": "Animate a progress spinner while tools run.",
4028
+ "config.key.ui.showContextStats": "context stats",
4029
+ "config.desc.ui.showContextStats": "Show context usage stats after each turn.",
4030
+ "config.key.ui.showCompaction": "compaction notice",
4031
+ "config.desc.ui.showCompaction": "Notify in chat when history compaction runs.",
4032
+ "config.key.retry.maxRetries": "max retries",
4033
+ "config.desc.retry.maxRetries": "Max retries for failed LLM requests (0-10).",
4034
+ "config.key.retry.baseDelay": "retry base delay",
4035
+ "config.desc.retry.baseDelay": "Base backoff delay between retries in ms (0-60000).",
4036
+ "config.key.retry.maxDelay": "retry max delay",
4037
+ "config.desc.retry.maxDelay": "Backoff delay cap between retries in ms (0-300000).",
4038
+ "config.key.retry.maxStreamRetries": "max stream retries",
4039
+ "config.desc.retry.maxStreamRetries": "Max retries for stalled or interrupted streams (0-10).",
4040
+ "config.key.retry.noDataTimeoutMs": "stream stall timeout (ms)",
4041
+ "config.desc.retry.noDataTimeoutMs": "Give up on a stream silent for this long, in ms (1000-600000).",
4042
+ "config.key.pricing.enabled": "cost tracking",
4043
+ "config.desc.pricing.enabled": "Track token usage and estimated cost per session.",
4044
+ "config.key.updater.enabled": "auto-update",
4045
+ "config.desc.updater.enabled": "Master switch for background update checks.",
4046
+ "config.key.updater.checkOnStart": "check on start",
4047
+ "config.desc.updater.checkOnStart": "Check for updates when the agent starts.",
4048
+ "config.key.updater.autoInstall": "auto-install updates",
4049
+ "config.desc.updater.autoInstall": "Install downloaded updates without asking.",
4050
+ "config.key.updater.intervalMs": "update check interval (ms)",
4051
+ "config.desc.updater.intervalMs": "Minimum time between update checks, in ms (0-86400000).",
4052
+ "config.key.skills.budget": "skills budget share",
4053
+ "config.desc.skills.budget": "Share of the system budget reserved for skill definitions (0.05-0.9).",
4054
+ "config.key.hallucination.judge.enabled": "hallucination judge",
4055
+ "config.desc.hallucination.judge.enabled": "Score answer confidence and flag likely hallucinations.",
4056
+ "config.key.subagent.resultMode": "subagent result mode",
4057
+ "config.desc.subagent.resultMode": "How subagent results return: inline text or via file.",
4058
+ "config.key.subagent.maxSummaryChars": "subagent summary limit",
4059
+ "config.desc.subagent.maxSummaryChars": "Max chars kept from a subagent summary (100-50000).",
4060
+ "config.key.subagent.maxParallelChunkQueries": "subagent parallel chunks",
4061
+ "config.desc.subagent.maxParallelChunkQueries": "Max parallel chunk queries per subagent wave (1-16).",
4062
+ "config.key.subagent.stableSystemPrompt": "stable subagent prompt",
4063
+ "config.desc.subagent.stableSystemPrompt": "Reuse one frozen system prompt for all subagents in a run.",
4064
+ "config.key.modelLoad.autoLoad": "auto-load model",
4065
+ "config.desc.modelLoad.autoLoad": "Load the model into the backend automatically on start.",
4066
+ "config.key.modelLoad.flashAttention": "flash attention",
4067
+ "config.desc.modelLoad.flashAttention": "Enable flash-attention kernels when loading the model.",
4068
+ "config.key.modelLoad.offloadKvCacheToGpu": "offload KV cache to GPU",
4069
+ "config.desc.modelLoad.offloadKvCacheToGpu": "Keep the KV cache in GPU memory when loading the model.",
4070
+ "config.key.modelLoad.evalBatchSize": "eval batch size",
4071
+ "config.desc.modelLoad.evalBatchSize": "Prompt-eval batch size at load time (1-4096).",
4072
+ "config.key.webSearch.enabled": "web search",
4073
+ "config.desc.webSearch.enabled": "Allow the agent to search the web.",
4074
+ "config.key.errorWebSearch.enabled": "search on error",
4075
+ "config.desc.errorWebSearch.enabled": "Search the web automatically when an error looks searchable.",
4076
+ "config.key.errorWebSearch.threshold": "error search threshold",
4077
+ "config.desc.errorWebSearch.threshold": "How many matching errors trigger a search (1-20).",
4078
+ "config.key.errorWebSearch.maxResults": "error search results",
4079
+ "config.desc.errorWebSearch.maxResults": "Max search results attached per error lookup (1-20).",
4080
+ "config.key.errorWebSearch.maxQueryChars": "error query limit",
4081
+ "config.desc.errorWebSearch.maxQueryChars": "Max chars of the error text sent per query (50-2000).",
4082
+ "config.key.errorWebSearch.maxSearchesPerSession": "error searches per session",
4083
+ "config.desc.errorWebSearch.maxSearchesPerSession": "Max automatic error searches per session (0-20).",
4084
+ "config.key.errorWebSearch.requestTimeoutMs": "error search timeout (ms)",
4085
+ "config.desc.errorWebSearch.requestTimeoutMs": "Timeout per automatic error-search request, in ms (1000-120000).",
4086
+ "config.key.browser.enabled": "browser tool",
4087
+ "config.desc.browser.enabled": "Allow the agent to drive a browser.",
4088
+ "config.key.browser.headless": "headless browser",
4089
+ "config.desc.browser.headless": "Run the browser without a visible window.",
4090
+ "config.key.browser.maxElements": "max page elements",
4091
+ "config.desc.browser.maxElements": "Max accessibility-tree elements per snapshot (1-200).",
4092
+ "config.key.browser.maxContentChars": "max page content",
4093
+ "config.desc.browser.maxContentChars": "Max chars of page content kept per snapshot (100-50000).",
4094
+ "config.key.browser.maxConsoleEntries": "max console entries",
4095
+ "config.desc.browser.maxConsoleEntries": "Max browser console entries collected per snapshot (1-200).",
4096
+ "config.key.browser.maxConsoleLineChars": "max console line",
4097
+ "config.desc.browser.maxConsoleLineChars": "Max chars per console line (50-5000).",
4098
+ "config.key.browser.viewportWidth": "viewport width",
4099
+ "config.desc.browser.viewportWidth": "Browser viewport width in px (320-4096).",
4100
+ "config.key.browser.viewportHeight": "viewport height",
4101
+ "config.desc.browser.viewportHeight": "Browser viewport height in px (200-2160).",
4102
+ "config.key.browser.navigationTimeout": "navigation timeout (ms)",
4103
+ "config.desc.browser.navigationTimeout": "Timeout per page navigation, in ms (1000-120000).",
4104
+ "config.key.security.maxRecursionDepth": "max recursion depth",
4105
+ "config.desc.security.maxRecursionDepth": "Max nested tool-call depth before refusal (0-20).",
4106
+ "config.key.security.maxFileOperations": "max file operations",
4107
+ "config.desc.security.maxFileOperations": "Max file operations per turn before refusal (0-10000).",
4108
+ "config.key.security.rateLimits.maxRequestsPerMinute": "max requests per minute",
4109
+ "config.desc.security.rateLimits.maxRequestsPerMinute": "LLM request rate cap per minute (1-1000).",
4110
+ "config.key.security.rateLimits.maxParallelTasks": "max parallel tasks",
4111
+ "config.desc.security.rateLimits.maxParallelTasks": "Cap on parallel subtasks (1-50).",
4112
+ "config.key.tools.defaultTags": "default tool tags",
4113
+ "config.desc.tools.defaultTags": "Tool groups always loaded without on-demand gating.",
4114
+ "config.key.security.bash.enabled": "bash command validation",
4115
+ "config.desc.security.bash.enabled": "Master switch for bash tool validation.",
4116
+ "config.key.security.bash.blockDangerousFlags": "block dangerous flags",
4117
+ "config.desc.security.bash.blockDangerousFlags": "Reject risky shell flags like --force in the bash tool.",
4118
+ "config.key.security.network.enabled": "network requests",
4119
+ "config.desc.security.network.enabled": "Master switch for outbound network checks (SSRF guard).",
4120
+ "config.key.security.bash.blacklist": "bash blacklist",
4121
+ "config.desc.security.bash.blacklist": "Commands always blocked in the bash tool (list).",
4122
+ "config.key.security.bash.whitelist": "bash whitelist",
4123
+ "config.desc.security.bash.whitelist": "Commands always allowed in the bash tool (list).",
4124
+ "config.key.security.bash.dangerousFlags": "dangerous flags",
4125
+ "config.desc.security.bash.dangerousFlags": "Command flags treated as dangerous (list).",
4126
+ "config.key.security.bash.dangerousOperators": "dangerous operators",
4127
+ "config.desc.security.bash.dangerousOperators": "Shell operators treated as dangerous (list).",
4128
+ "config.key.security.paths.denied": "denied paths",
4129
+ "config.desc.security.paths.denied": "Paths always off-limits for file tools (list).",
4130
+ "config.key.security.paths.allowed": "allowed paths",
4131
+ "config.desc.security.paths.allowed": "Extra paths allowed outside the workspace (list).",
4132
+ "config.key.security.network.deniedDomains": "denied domains",
4133
+ "config.desc.security.network.deniedDomains": "Domains the agent may never contact (list).",
4134
+ "config.key.security.network.allowedDomains": "allowed domains",
4135
+ "config.desc.security.network.allowedDomains": "Domains the agent may contact (list; empty means any).",
4136
+ "config.key.security.network.requestTimeout": "network timeout (ms)",
4137
+ "config.desc.security.network.requestTimeout": "Timeout per outbound tool request, in ms (1000-120000).",
4138
+ "config.key.security.network.maxResponseSize": "max response size",
4139
+ "config.desc.security.network.maxResponseSize": "Max bytes kept per outbound response (1024-1000000).",
4140
+ "config.key.security.contentScan.dangerousPatterns": "dangerous patterns",
4141
+ "config.desc.security.contentScan.dangerousPatterns": "Regular expressions searched in file contents before writing.",
4142
+ "config.key.security.auditNotifier.enabled": "audit notifier",
4143
+ "config.desc.security.auditNotifier.enabled": "Send security-audit events to a file or webhook.",
4144
+ "config.key.security.auditNotifier.filePath": "audit log path",
4145
+ "config.desc.security.auditNotifier.filePath": "File the audit events are appended to.",
4146
+ "config.key.security.auditNotifier.webhookUrl": "audit webhook URL",
4147
+ "config.desc.security.auditNotifier.webhookUrl": "Webhook the audit events are posted to.",
4148
+ "config.key.security.auditNotifier.webhookTimeout": "audit webhook timeout (ms)",
4149
+ "config.desc.security.auditNotifier.webhookTimeout": "Timeout per webhook post, in ms (1000-60000).",
4150
+ "config.key.security.auditNotifier.minSeverity": "audit min severity",
4151
+ "config.desc.security.auditNotifier.minSeverity": "Lowest severity that still notifies (low/medium/high/critical).",
4152
+ "config.key.security.auditNotifier.eventTypes": "audit event types",
4153
+ "config.desc.security.auditNotifier.eventTypes": "Which audit event types notify; none selected means all.",
4154
+ "config.key.security.auditNotifier.maxRetries": "audit max retries",
4155
+ "config.desc.security.auditNotifier.maxRetries": "Retries per failed notification post (0-10).",
4156
+ "config.key.security.sessionEncryption.keyPath": "encryption key path",
4157
+ "config.desc.security.sessionEncryption.keyPath": "File holding the session-encryption key.",
4158
+ "config.key.security.sessionEncryption.encryptHistory": "encrypt chat history",
4159
+ "config.desc.security.sessionEncryption.encryptHistory": "Encrypt the saved chat history on disk.",
4160
+ "config.key.security.sessionEncryption.encryptSessionLog": "encrypt session log",
4161
+ "config.desc.security.sessionEncryption.encryptSessionLog": "Encrypt the saved session.jsonl log on disk.",
4162
+ "config.key.pricing.overrides": "pricing overrides",
4163
+ "config.desc.pricing.overrides": "Per-model price table overriding built-ins.",
4164
+ "config.key.modelCapabilities": "model capabilities",
4165
+ "config.desc.modelCapabilities": "Manual vision/tools overrides per model id.",
4166
+ "config.key.experts": "MoE experts",
4167
+ "config.desc.experts": "Expert roster for the MoE orchestrator.",
4168
+ "config.enum.text": "text",
4169
+ "config.enum.file": "file",
4170
+ "config.enum.critical": "critical"
3872
4171
  };
3873
4172
  });
3874
4173
 
@@ -4219,7 +4518,9 @@ var init_ru = __esm(() => {
4219
4518
  "cli.manage_config": "Управление конфигурацией",
4220
4519
  "cli.config_key": "Ключ конфига (напр., model, provider.baseUrl)",
4221
4520
  "cli.set_value": "Установить значение",
4521
+ "cli.config_force": "Обойти проверку и записать сырое значение как есть",
4222
4522
  "cli.set_done": "Установлено {key}={value}",
4523
+ "cli.config_invalid": "Недопустимое значение для '{key}' ({reason}). Конфиг не изменён.",
4223
4524
  "cli.show_config": "Показать действующую конфигурацию (секреты скрыты; используйте --show-secrets)",
4224
4525
  "cli.migrate_config": "Мигрировать legacy config.json в domain-формат",
4225
4526
  "cli.manage_models": "Управление моделями",
@@ -4415,6 +4716,7 @@ var init_ru = __esm(() => {
4415
4716
  "repl.last_action_none": "Нет недавнего действия для показа.",
4416
4717
  "repl.status": "Показать компактную строку статуса",
4417
4718
  "repl.status_usage": "Использование: /status",
4719
+ "repl.security": "Показать конфигурацию безопасности (вкл/выкл по областям)",
4418
4720
  "repl.plugins": "Список загруженных плагинов",
4419
4721
  "repl.plugins_usage": "Использование: /plugins [--all]",
4420
4722
  "repl.sessions": "Список всех сессий (* активная)",
@@ -5033,18 +5335,114 @@ var init_ru = __esm(() => {
5033
5335
  "config.enum.max": "максимум",
5034
5336
  "config.enum.en": "английский",
5035
5337
  "config.enum.ru": "русский",
5338
+ "config.enum.security_block": "блокировка безопасности",
5339
+ "config.enum.bash_command": "bash-команда",
5340
+ "config.enum.file_operation": "операция с файлом",
5341
+ "config.enum.network_request": "сетевой запрос",
5342
+ "config.enum.tool_call": "вызов инструмента",
5343
+ "config.enum.authentication": "аутентификация",
5344
+ "config.enum.configuration_change": "изменение конфигурации",
5345
+ "config.enum.session_start": "старт сессии",
5346
+ "config.enum.session_end": "конец сессии",
5036
5347
  "web.settings.title": "настройки",
5037
5348
  "web.settings.general": "Общие",
5038
5349
  "web.settings.model": "Модель и провайдер",
5039
5350
  "web.settings.context": "Контекст",
5040
5351
  "web.settings.reasoning": "Рассуждения",
5041
5352
  "web.settings.agent": "Агент",
5353
+ "web.settings.network": "Сеть",
5354
+ "web.settings.browser": "Браузер",
5355
+ "web.settings.sessions": "Сессии",
5042
5356
  "web.settings.ui": "Интерфейс и тема",
5043
5357
  "web.settings.memory": "Память",
5044
5358
  "web.settings.skills": "Навыки",
5045
5359
  "web.settings.plugins": "Плагины · MCP",
5046
5360
  "web.settings.security": "Безопасность",
5047
5361
  "web.settings.advanced": "Дополнительно",
5362
+ "web.settings.search_placeholder": "поиск по настройкам",
5363
+ "web.settings.search_empty": "ничего не найдено",
5364
+ "web.settings.table_invalid": "сначала заполните обязательные поля ({field})",
5365
+ "web.settings.sec.general.interface": "Интерфейс",
5366
+ "web.settings.sec.general.agent": "Цикл агента",
5367
+ "web.settings.sec.general.agent.desc": "Как долго и настойчиво агент работает до остановки.",
5368
+ "web.settings.sec.general.provider": "Провайдеры",
5369
+ "web.settings.sec.model.tuning": "Производительность",
5370
+ "web.settings.sec.model.tuning.desc": "Лимит токенов ответа и загрузка модели в память.",
5371
+ "web.settings.sec.model.capabilities": "Возможности",
5372
+ "web.settings.sec.model.capabilities.desc": "Ручные переопределения vision/tools, если определение модели ошибается.",
5373
+ "web.settings.sec.context.window": "Окно контекста",
5374
+ "web.settings.sec.context.window.desc": "Общее окно и его деление между системным промптом, ответом и историей.",
5375
+ "web.settings.sec.context.compaction": "Сжатие",
5376
+ "web.settings.sec.context.compaction.desc": "Когда старая история сворачивается в сводку для освобождения места.",
5377
+ "web.settings.sec.context.instructions": "Инструкции",
5378
+ "web.settings.sec.context.instructions.desc": "Что делать, если AGENTS.md или карта проекта не влезают в промпт.",
5379
+ "web.settings.sec.context.log": "Журнал контекста",
5380
+ "web.settings.sec.context.log.desc": "Записывать каждый промпт в файл диффов рядом с сессией.",
5381
+ "web.settings.sec.reasoning.display": "Показ",
5382
+ "web.settings.sec.reasoning.effort": "Глубина",
5383
+ "web.settings.sec.reasoning.effort.desc": "Авто выбирает уровень на каждом шаге внутри диапазона; ручной режим его отключает.",
5384
+ "web.settings.sec.agent.moe": "Смесь экспертов",
5385
+ "web.settings.sec.agent.moe.desc": "Делит работу на подзадачи экспертов через планировщик; медленнее, но сильнее на многошаговых задачах.",
5386
+ "web.settings.sec.agent.critic": "Критик",
5387
+ "web.settings.sec.agent.critic.desc": "Второй проход, проверяющий работу агента перед ответом.",
5388
+ "web.settings.sec.agent.tools": "Инструменты и навыки",
5389
+ "web.settings.sec.agent.tools.desc": "Какие инструменты видны сразу и сколько промпта могут занять навыки.",
5390
+ "web.settings.sec.agent.subagent": "Субагенты",
5391
+ "web.settings.sec.agent.subagent.desc": "Как возвращаются результаты субагентов и как они распараллеливаются.",
5392
+ "web.settings.sec.agent.hallucination": "Проверка галлюцинаций",
5393
+ "web.settings.sec.agent.hallucination.desc": "Проверять ответ на связность перед показом.",
5394
+ "web.settings.sec.network.web": "Веб-поиск",
5395
+ "web.settings.sec.network.web.desc": "Главный выключатель инструмента web_search.",
5396
+ "web.settings.sec.network.error": "Автопоиск по ошибке",
5397
+ "web.settings.sec.network.error.desc": "Искать в интернете, когда одна и та же ошибка повторяется.",
5398
+ "web.settings.sec.browser.main": "Браузер",
5399
+ "web.settings.sec.browser.limits": "Лимиты",
5400
+ "web.settings.sec.browser.limits.desc": "Ограничения, чтобы снимок страницы влезал в контекст.",
5401
+ "web.settings.sec.browser.viewport": "Окно и таймауты",
5402
+ "web.settings.sec.sessions.main": "Сессии",
5403
+ "web.settings.sec.sessions.main.desc": "Сохранение, имена и сколько прошлых сессий хранить.",
5404
+ "web.settings.sec.sessions.isolation": "Изоляция",
5405
+ "web.settings.sec.sessions.isolation.desc": "Держать плагины и временные файлы отдельно для каждой сессии.",
5406
+ "web.settings.sec.ui.chat": "Вывод в чат",
5407
+ "web.settings.sec.ui.chat.desc": "Строки статуса, прогресс и метры контекста в ленте чата.",
5408
+ "web.settings.sec.ui.theme": "Тема",
5409
+ "web.settings.sec.ui.theme.desc": "Цветовая схема веб-интерфейса. Хранится в браузере, а не в файле конфигурации.",
5410
+ "web.settings.sec.memory.add": "Добавить заметку",
5411
+ "web.settings.memory_add_title": "новая запись памяти",
5412
+ "config.field.name": "имя",
5413
+ "config.field.model": "модель",
5414
+ "config.field.tool_tags": "теги инструментов",
5415
+ "config.field.max_attempts": "попытки",
5416
+ "config.field.description": "описание",
5417
+ "config.field.input": "вход $/1M",
5418
+ "config.field.output": "выход $/1M",
5419
+ "config.field.cachedInput": "кеш $/1M",
5420
+ "config.field.cacheWrite": "запись $/1M",
5421
+ "config.field.vision": "изображения",
5422
+ "config.field.tools": "инструменты",
5423
+ "web.settings.sec.security.switches": "Переключатели",
5424
+ "web.settings.sec.security.switches.desc": "Главные выключатели по каждой защите. Выключение отключает всю группу ниже.",
5425
+ "web.settings.sec.security.limits": "Лимиты",
5426
+ "web.settings.sec.security.limits.desc": "Ограничения глубины, объёма и частоты для активности инструментов.",
5427
+ "web.settings.sec.security.bash": "Правила bash",
5428
+ "web.settings.sec.security.bash.desc": "Команды, флаги и операторы, которые bash-тул отклоняет.",
5429
+ "web.settings.sec.security.paths": "Правила путей",
5430
+ "web.settings.sec.security.paths.desc": "Glob-шаблоны запрещённых путей или, если задано, единственно разрешённых.",
5431
+ "web.settings.sec.security.network": "Правила сети",
5432
+ "web.settings.sec.security.network.desc": "Заблокированные домены или, если задано, единственно разрешённые.",
5433
+ "web.settings.sec.security.scan": "Сканирование контента",
5434
+ "web.settings.sec.security.scan.desc": "Шаблоны, которые ищутся в содержимом файлов перед записью.",
5435
+ "web.settings.sec.security.audit": "Журнал аудита",
5436
+ "web.settings.sec.security.audit.desc": "Отправлять события безопасности в файл или вебхук.",
5437
+ "web.settings.sec.security.encryption": "Шифрование сессий",
5438
+ "web.settings.sec.security.encryption.desc": "Шифровать историю чата и журнал сессии на диске.",
5439
+ "web.settings.sec.security.access": "Доступ",
5440
+ "web.settings.sec.advanced.diagnostics": "Диагностика",
5441
+ "web.settings.sec.advanced.diagnostics.desc": "Подробность логов и установленная версия.",
5442
+ "web.settings.sec.advanced.retry": "Повторы",
5443
+ "web.settings.sec.advanced.retry.desc": "Пауза между повторами упавших или зависших запросов к провайдеру.",
5444
+ "web.settings.sec.advanced.service": "Сервис",
5445
+ "web.settings.sec.advanced.service.desc": "Учёт стоимости, цены и фоновая проверка обновлений.",
5048
5446
  "web.settings.add": "добавить",
5049
5447
  "web.settings.forget": "забыть",
5050
5448
  "web.settings.search": "поиск",
@@ -5082,6 +5480,11 @@ var init_ru = __esm(() => {
5082
5480
  "web.settings.provider_priority": "приоритет",
5083
5481
  "web.settings.provider_rpm": "запросов / мин",
5084
5482
  "web.settings.provider_parallel": "макс. параллельно",
5483
+ "web.settings.provider_max_tokens": "макс. токенов ответа",
5484
+ "web.settings.provider_cache_mechanism": "механизм кеша",
5485
+ "web.settings.provider_cache_report": "формат отчёта кеша",
5486
+ "web.settings.provider_cache_flags": "флаги кеша",
5487
+ "web.settings.provider_retry": "повторы",
5085
5488
  "web.settings.provider_required": "тип и base URL обязательны",
5086
5489
  "web.settings.provider_invalid": "некорректное числовое значение",
5087
5490
  "web.settings.provider_active_guard": "нельзя удалить активного провайдера — сначала переключись",
@@ -5114,6 +5517,14 @@ var init_ru = __esm(() => {
5114
5517
  "web.settings.disabled": "отключён",
5115
5518
  "web.settings.mcp_servers": "MCP-серверы",
5116
5519
  "web.settings.no_mcp": "MCP-серверы не настроены",
5520
+ "web.settings.mcp_add": "добавить MCP-сервер",
5521
+ "web.settings.mcp_edit_title": "править MCP-сервер",
5522
+ "web.settings.mcp_required": "нужны имя и command (stdio) или URL (sse/http)",
5523
+ "web.settings.mcp_invalid": "неверное значение: timeout 1000–300000 мс, args/env/headers — JSON",
5524
+ "web.settings.lsp_servers": "LSP-серверы",
5525
+ "web.settings.no_lsp": "LSP-серверы не настроены",
5526
+ "web.settings.lsp_note": "изменения LSP сохраняются в конфиг и применяются при следующем запуске.",
5527
+ "web.settings.lsp_unavailable": "LSP недоступен",
5117
5528
  "web.settings.loading": "загрузка…",
5118
5529
  "web.input.placeholder": "ввод сообщения… (/ — команды)",
5119
5530
  "web.input.enter": "Enter — отправить",
@@ -5172,6 +5583,8 @@ var init_ru = __esm(() => {
5172
5583
  "web.command.reasoning": "показ рассуждений и уровень",
5173
5584
  "web.command.verbose": "уровень детализации UI",
5174
5585
  "web.command.context": "показать или задать окно контекста",
5586
+ "web.command.security": "показать флаги безопасности или записать ключ",
5587
+ "web.security.unknown_sub": "неизвестная подкоманда: security {sub}",
5175
5588
  "web.command.session": "показать сессии или активировать сессию",
5176
5589
  "web.command.export": "экспорт активной сессии в файл",
5177
5590
  "web.command.memory": "просмотр и правка глобальной памяти",
@@ -5230,7 +5643,7 @@ var init_ru = __esm(() => {
5230
5643
  "config.desc.critic.timeoutMs": "Таймаут вызова критика (fail-open).",
5231
5644
  "config.desc.logLevel": "Подробность диагностических логов.",
5232
5645
  "config.desc.locale": "Язык интерфейса и сообщений агента.",
5233
- "config.desc.version": "Установленная версия MMA (только чтение).",
5646
+ "config.desc.version": "Установленная версия MMA.",
5234
5647
  "config.desc.security.enabled": "Главный выключатель модуля безопасности (проверки путей, сканы, лимиты).",
5235
5648
  "config.desc.security.paths.enabled": "Ограничивать файловые операции рабочей папкой и блокировать пути вне неё.",
5236
5649
  "config.desc.security.contentScan.enabled": "Проверять содержимое файлов на опасные паттерны перед записью.",
@@ -5301,7 +5714,192 @@ var init_ru = __esm(() => {
5301
5714
  "web.setup.finish": "Завершить настройку",
5302
5715
  "web.setup.saving": "Сохранение…",
5303
5716
  "web.setup.saved_warning": "Сохранено с предупреждениями: {warning}",
5304
- "web.setup.failed": "Не удалось завершить настройку. Проверьте значения и попробуйте снова."
5717
+ "web.setup.failed": "Не удалось завершить настройку. Проверьте значения и попробуйте снова.",
5718
+ "config.key.provider.fallback": "резервные провайдеры",
5719
+ "config.desc.provider.fallback": "Переходить к следующей записи провайдера при сбое активного.",
5720
+ "config.key.provider.maxCompletionTokens": "макс. токенов ответа",
5721
+ "config.desc.provider.maxCompletionTokens": "Жесткий лимит токенов ответа на запрос (512-128000).",
5722
+ "config.key.contextBudget.compactionThreshold": "порог компакции",
5723
+ "config.desc.contextBudget.compactionThreshold": "Доля загрузки истории, разрешающая периодическую компакцию (0,05-0,9).",
5724
+ "config.key.contextBudget.compactionMinLoad": "мин. загрузка компакции",
5725
+ "config.desc.contextBudget.compactionMinLoad": "Минимальная загрузка истории для запуска компакции (0,05-0,9).",
5726
+ "config.key.instructions.summarize": "суммировать инструкции",
5727
+ "config.desc.instructions.summarize": "Суммировать переполненные блоки AGENTS.md/карты проекта вместо обрезки.",
5728
+ "config.key.contextLog.enabled": "лог контекста",
5729
+ "config.desc.contextLog.enabled": "Писать уходящий в LLM контекст каждой итерации в <session>/context.diff.",
5730
+ "config.key.contextLog.redact": "чистить лог контекста",
5731
+ "config.desc.contextLog.redact": "Вырезать опознаваемые секреты (токены, ключи) из лога контекста.",
5732
+ "config.key.reasoning.min": "мин. рассуждения",
5733
+ "config.desc.reasoning.min": "Нижняя граница диапазона усилий рассуждений.",
5734
+ "config.key.reasoning.max": "макс. рассуждения",
5735
+ "config.desc.reasoning.max": "Верхняя граница диапазона усилий рассуждений.",
5736
+ "config.key.reasoning.baseline": "базовые рассуждения",
5737
+ "config.desc.reasoning.baseline": "Усилия рассуждений по умолчанию, если модель не дала сигнала.",
5738
+ "config.key.reasoning.overrideCooldown": "кулдаун переопределения",
5739
+ "config.desc.reasoning.overrideCooldown": "Ходов до повторного принятия переопределения рассуждений (1-60).",
5740
+ "config.key.autoPlan": "автоплан",
5741
+ "config.desc.autoPlan": "Позволять агенту автоматически строить план для многошаговых задач.",
5742
+ "config.key.tools.enableOnDemand": "тулы по требованию",
5743
+ "config.desc.tools.enableOnDemand": "Подгружать узкие группы тулов по требованию вместо показа всех.",
5744
+ "config.key.session.autoSave": "автосохранение сессии",
5745
+ "config.desc.session.autoSave": "Сохранять лог сессии после каждого хода.",
5746
+ "config.key.session.maxSessions": "макс. сессий",
5747
+ "config.desc.session.maxSessions": "Сколько последних сессий хранить на диске (1-500).",
5748
+ "config.key.session.isolateMemory": "изолировать память сессии",
5749
+ "config.desc.session.isolateMemory": "Держать память сессии отдельно от глобальной.",
5750
+ "config.key.session.autoName": "автоназвания сессий",
5751
+ "config.desc.session.autoName": "Выводить имя сессии из первого сообщения (уточняется LLM).",
5752
+ "config.key.sessionIsolation.enabled": "изоляция сессий",
5753
+ "config.desc.sessionIsolation.enabled": "Главный выключатель изоляции сессий (плагины, временные файлы).",
5754
+ "config.key.sessionIsolation.isolatePlugins": "изолировать плагины",
5755
+ "config.desc.sessionIsolation.isolatePlugins": "Выдавать каждой сессии собственную песочницу плагинов.",
5756
+ "config.key.sessionIsolation.isolateTempFiles": "изолировать временные файлы",
5757
+ "config.desc.sessionIsolation.isolateTempFiles": "Выдавать каждой сессии отдельную папку временных файлов.",
5758
+ "config.key.ui.spinner": "спиннер",
5759
+ "config.desc.ui.spinner": "Показывать анимированный спиннер во время работы тулов.",
5760
+ "config.key.ui.showContextStats": "статистика контекста",
5761
+ "config.desc.ui.showContextStats": "Показывать статистику использования контекста после каждого хода.",
5762
+ "config.key.ui.showCompaction": "уведомление о компакции",
5763
+ "config.desc.ui.showCompaction": "Сообщать в чате о запуске компакции истории.",
5764
+ "config.key.retry.maxRetries": "макс. повторов",
5765
+ "config.desc.retry.maxRetries": "Максимум повторов упавших LLM-запросов (0-10).",
5766
+ "config.key.retry.baseDelay": "базовая задержка повтора",
5767
+ "config.desc.retry.baseDelay": "Базовая задержка между повторами в мс (0-60000).",
5768
+ "config.key.retry.maxDelay": "макс. задержка повтора",
5769
+ "config.desc.retry.maxDelay": "Потолок задержки между повторами в мс (0-300000).",
5770
+ "config.key.retry.maxStreamRetries": "макс. повторов стрима",
5771
+ "config.desc.retry.maxStreamRetries": "Максимум повторов зависших или прерванных стримов (0-10).",
5772
+ "config.key.retry.noDataTimeoutMs": "таймаут застоя стрима (мс)",
5773
+ "config.desc.retry.noDataTimeoutMs": "Сдаваться, если стрим молчит дольше этого времени, в мс (1000-600000).",
5774
+ "config.key.pricing.enabled": "учет стоимости",
5775
+ "config.desc.pricing.enabled": "Считать токены и примерную стоимость по сессиям.",
5776
+ "config.key.updater.enabled": "автообновление",
5777
+ "config.desc.updater.enabled": "Главный выключатель фоновой проверки обновлений.",
5778
+ "config.key.updater.checkOnStart": "проверка при старте",
5779
+ "config.desc.updater.checkOnStart": "Проверять обновления при старте агента.",
5780
+ "config.key.updater.autoInstall": "автоустановка обновлений",
5781
+ "config.desc.updater.autoInstall": "Устанавливать скачанные обновления без спроса.",
5782
+ "config.key.updater.intervalMs": "интервал проверки (мс)",
5783
+ "config.desc.updater.intervalMs": "Минимальный интервал между проверками, в мс (0-86400000).",
5784
+ "config.key.skills.budget": "доля бюджета скиллов",
5785
+ "config.desc.skills.budget": "Доля системного бюджета под определения скиллов (0,05-0,9).",
5786
+ "config.key.hallucination.judge.enabled": "судья галлюцинаций",
5787
+ "config.desc.hallucination.judge.enabled": "Оценивать уверенность ответа и помечать вероятные галлюцинации.",
5788
+ "config.key.subagent.resultMode": "режим результата субагентов",
5789
+ "config.desc.subagent.resultMode": "Как возвращать результаты субагентов: текстом или через файл.",
5790
+ "config.key.subagent.maxSummaryChars": "лимит сводки субагента",
5791
+ "config.desc.subagent.maxSummaryChars": "Максимум символов сводки субагента (100-50000).",
5792
+ "config.key.subagent.maxParallelChunkQueries": "параллельные чанки субагента",
5793
+ "config.desc.subagent.maxParallelChunkQueries": "Максимум параллельных запросов чанков за волну субагента (1-16).",
5794
+ "config.key.subagent.stableSystemPrompt": "стабильный промпт субагента",
5795
+ "config.desc.subagent.stableSystemPrompt": "Переиспользовать один замороженный системный промпт для всех субагентов прогона.",
5796
+ "config.key.modelLoad.autoLoad": "автозагрузка модели",
5797
+ "config.desc.modelLoad.autoLoad": "Автоматически загружать модель в бэкенд при старте.",
5798
+ "config.key.modelLoad.flashAttention": "flash attention",
5799
+ "config.desc.modelLoad.flashAttention": "Включать flash-attention ядра при загрузке модели.",
5800
+ "config.key.modelLoad.offloadKvCacheToGpu": "выгружать KV-кэш в GPU",
5801
+ "config.desc.modelLoad.offloadKvCacheToGpu": "Держать KV-кэш в памяти GPU при загрузке модели.",
5802
+ "config.key.modelLoad.evalBatchSize": "размер eval-батча",
5803
+ "config.desc.modelLoad.evalBatchSize": "Размер батча оценки промпта при загрузке (1-4096).",
5804
+ "config.key.webSearch.enabled": "веб-поиск",
5805
+ "config.desc.webSearch.enabled": "Разрешить агенту искать в интернете.",
5806
+ "config.key.errorWebSearch.enabled": "поиск при ошибке",
5807
+ "config.desc.errorWebSearch.enabled": "Автоматически искать в интернете при ошибке, похожей на гуглящуюся.",
5808
+ "config.key.errorWebSearch.threshold": "порог поиска ошибок",
5809
+ "config.desc.errorWebSearch.threshold": "Сколько совпадающих ошибок запускает поиск (1-20).",
5810
+ "config.key.errorWebSearch.maxResults": "результатов поиска ошибок",
5811
+ "config.desc.errorWebSearch.maxResults": "Максимум результатов поиска на запрос об ошибке (1-20).",
5812
+ "config.key.errorWebSearch.maxQueryChars": "лимит запроса ошибки",
5813
+ "config.desc.errorWebSearch.maxQueryChars": "Максимум символов текста ошибки на запрос (50-2000).",
5814
+ "config.key.errorWebSearch.maxSearchesPerSession": "поисков ошибок за сессию",
5815
+ "config.desc.errorWebSearch.maxSearchesPerSession": "Максимум автопоисков ошибок за сессию (0-20).",
5816
+ "config.key.errorWebSearch.requestTimeoutMs": "таймаут поиска ошибок (мс)",
5817
+ "config.desc.errorWebSearch.requestTimeoutMs": "Таймаут одного автопоиска ошибки, в мс (1000-120000).",
5818
+ "config.key.browser.enabled": "тул браузера",
5819
+ "config.desc.browser.enabled": "Разрешить агенту управлять браузером.",
5820
+ "config.key.browser.headless": "безголовый браузер",
5821
+ "config.desc.browser.headless": "Запускать браузер без видимого окна.",
5822
+ "config.key.browser.maxElements": "макс. элементов страницы",
5823
+ "config.desc.browser.maxElements": "Максимум элементов accessibility-дерева на снимок (1-200).",
5824
+ "config.key.browser.maxContentChars": "макс. содержимого страницы",
5825
+ "config.desc.browser.maxContentChars": "Максимум символов содержимого страницы на снимок (100-50000).",
5826
+ "config.key.browser.maxConsoleEntries": "макс. записей консоли",
5827
+ "config.desc.browser.maxConsoleEntries": "Максимум записей консоли браузера на снимок (1-200).",
5828
+ "config.key.browser.maxConsoleLineChars": "макс. строки консоли",
5829
+ "config.desc.browser.maxConsoleLineChars": "Максимум символов на строку консоли (50-5000).",
5830
+ "config.key.browser.viewportWidth": "ширина вьюпорта",
5831
+ "config.desc.browser.viewportWidth": "Ширина вьюпорта браузера в px (320-4096).",
5832
+ "config.key.browser.viewportHeight": "высота вьюпорта",
5833
+ "config.desc.browser.viewportHeight": "Высота вьюпорта браузера в px (200-2160).",
5834
+ "config.key.browser.navigationTimeout": "таймаут навигации (мс)",
5835
+ "config.desc.browser.navigationTimeout": "Таймаут одной навигации страницы, в мс (1000-120000).",
5836
+ "config.key.security.maxRecursionDepth": "макс. глубина рекурсии",
5837
+ "config.desc.security.maxRecursionDepth": "Макс. глубина вложенных вызовов тулов до отказа (0-20).",
5838
+ "config.key.security.maxFileOperations": "макс. файловых операций",
5839
+ "config.desc.security.maxFileOperations": "Максимум файловых операций за ход до отказа (0-10000).",
5840
+ "config.key.security.rateLimits.maxRequestsPerMinute": "макс. запросов в минуту",
5841
+ "config.desc.security.rateLimits.maxRequestsPerMinute": "Лимит LLM-запросов в минуту (1-1000).",
5842
+ "config.key.security.rateLimits.maxParallelTasks": "макс. параллельных задач",
5843
+ "config.desc.security.rateLimits.maxParallelTasks": "Лимит параллельных подзадач (1-50).",
5844
+ "config.key.tools.defaultTags": "теги тулов по умолчанию",
5845
+ "config.desc.tools.defaultTags": "Группы тулов, всегда загружаемые без gating по требованию.",
5846
+ "config.key.security.bash.enabled": "проверка bash-команд",
5847
+ "config.desc.security.bash.enabled": "Главный выключатель проверки bash-команд.",
5848
+ "config.key.security.bash.blockDangerousFlags": "блокировать опасные флаги",
5849
+ "config.desc.security.bash.blockDangerousFlags": "Отклонять рискованные флаги shell (например --force) в bash-туле.",
5850
+ "config.key.security.network.enabled": "сетевые запросы",
5851
+ "config.desc.security.network.enabled": "Главный выключатель проверок исходящих сетевых запросов (защита от SSRF).",
5852
+ "config.key.security.bash.blacklist": "черный список bash",
5853
+ "config.desc.security.bash.blacklist": "Команды, всегда блокируемые в bash-туле (список).",
5854
+ "config.key.security.bash.whitelist": "белый список bash",
5855
+ "config.desc.security.bash.whitelist": "Команды, всегда разрешенные в bash-туле (список).",
5856
+ "config.key.security.bash.dangerousFlags": "опасные флаги",
5857
+ "config.desc.security.bash.dangerousFlags": "Флаги команд, считающиеся опасными (список).",
5858
+ "config.key.security.bash.dangerousOperators": "опасные операторы",
5859
+ "config.desc.security.bash.dangerousOperators": "Шелл-операторы, считающиеся опасными (список).",
5860
+ "config.key.security.paths.denied": "запрещенные пути",
5861
+ "config.desc.security.paths.denied": "Пути, всегда закрытые для файловых тулов (список).",
5862
+ "config.key.security.paths.allowed": "разрешенные пути",
5863
+ "config.desc.security.paths.allowed": "Дополнительные пути, разрешенные вне workspace (список).",
5864
+ "config.key.security.network.deniedDomains": "запрещенные домены",
5865
+ "config.desc.security.network.deniedDomains": "Домены, к которым агенту нельзя обращаться (список).",
5866
+ "config.key.security.network.allowedDomains": "разрешенные домены",
5867
+ "config.desc.security.network.allowedDomains": "Домены, к которым можно обращаться (список; пусто - любые).",
5868
+ "config.key.security.network.requestTimeout": "сетевой таймаут (мс)",
5869
+ "config.desc.security.network.requestTimeout": "Таймаут одного исходящего запроса тула, в мс (1000-120000).",
5870
+ "config.key.security.network.maxResponseSize": "макс. размер ответа",
5871
+ "config.desc.security.network.maxResponseSize": "Максимум байт исходящего ответа (1024-1000000).",
5872
+ "config.key.security.contentScan.dangerousPatterns": "опасные паттерны",
5873
+ "config.desc.security.contentScan.dangerousPatterns": "Регулярные выражения, которые ищутся в содержимом файлов перед записью.",
5874
+ "config.key.security.auditNotifier.enabled": "аудит-уведомитель",
5875
+ "config.desc.security.auditNotifier.enabled": "Отправлять события аудита безопасности в файл или вебхук.",
5876
+ "config.key.security.auditNotifier.filePath": "путь аудит-лога",
5877
+ "config.desc.security.auditNotifier.filePath": "Файл, в который дописываются события аудита.",
5878
+ "config.key.security.auditNotifier.webhookUrl": "URL аудит-вебхука",
5879
+ "config.desc.security.auditNotifier.webhookUrl": "Вебхук, на который отправляются события аудита.",
5880
+ "config.key.security.auditNotifier.webhookTimeout": "таймаут аудит-вебхука (мс)",
5881
+ "config.desc.security.auditNotifier.webhookTimeout": "Таймаут одной отправки вебхука, в мс (1000-60000).",
5882
+ "config.key.security.auditNotifier.minSeverity": "мин. серьезность аудита",
5883
+ "config.desc.security.auditNotifier.minSeverity": "Низшая серьезность, при которой еще уведомлять (low/medium/high/critical).",
5884
+ "config.key.security.auditNotifier.eventTypes": "типы событий аудита",
5885
+ "config.desc.security.auditNotifier.eventTypes": "Какие типы событий аудита уведомляют; ничего не выбрано - все.",
5886
+ "config.key.security.auditNotifier.maxRetries": "макс. повторов аудита",
5887
+ "config.desc.security.auditNotifier.maxRetries": "Повторов одной упавшей отправки уведомления (0-10).",
5888
+ "config.key.security.sessionEncryption.keyPath": "путь ключа шифрования",
5889
+ "config.desc.security.sessionEncryption.keyPath": "Файл с ключом шифрования сессий.",
5890
+ "config.key.security.sessionEncryption.encryptHistory": "шифровать историю чата",
5891
+ "config.desc.security.sessionEncryption.encryptHistory": "Шифровать сохраненную историю чата на диске.",
5892
+ "config.key.security.sessionEncryption.encryptSessionLog": "шифровать лог сессии",
5893
+ "config.desc.security.sessionEncryption.encryptSessionLog": "Шифровать сохраненный лог session.jsonl на диске.",
5894
+ "config.key.pricing.overrides": "переопределения цен",
5895
+ "config.desc.pricing.overrides": "По-модельная таблица цен поверх встроенной.",
5896
+ "config.key.modelCapabilities": "возможности моделей",
5897
+ "config.desc.modelCapabilities": "Ручные переопределения vision/tools по id модели.",
5898
+ "config.key.experts": "эксперты MoE",
5899
+ "config.desc.experts": "Состав экспертов для MoE-оркестратора.",
5900
+ "config.enum.text": "текст",
5901
+ "config.enum.file": "файл",
5902
+ "config.enum.critical": "критический"
5305
5903
  };
5306
5904
  });
5307
5905
 
@@ -33171,6 +33769,879 @@ var init_budget = __esm(() => {
33171
33769
  init_i18n();
33172
33770
  });
33173
33771
 
33772
+ // src/config/registry-extra.ts
33773
+ function bool(key, domain, reconfigure, get, set) {
33774
+ return { key, aliases: [], domain, valueType: "bool", reconfigure, get, set };
33775
+ }
33776
+ function int(key, domain, min, max, step, reconfigure, get, set) {
33777
+ return { key, aliases: [], domain, valueType: "int", min, max, step, reconfigure, get, set };
33778
+ }
33779
+ function share(key, domain, reconfigure, get, set) {
33780
+ return { key, aliases: [], domain, valueType: "share", min: 0.05, max: 0.9, step: 0.01, reconfigure, get, set };
33781
+ }
33782
+ function enumOf(key, domain, values, reconfigure, get, set) {
33783
+ return { key, aliases: [], domain, valueType: "enum", enumValues: values, reconfigure, get, set };
33784
+ }
33785
+ function list(key, domain, get, set, editor) {
33786
+ return { key, aliases: [], domain, valueType: "list", reconfigure: false, editor, get, set };
33787
+ }
33788
+ function str(key, domain, get, set) {
33789
+ return { key, aliases: [], domain, valueType: "string", reconfigure: false, get, set };
33790
+ }
33791
+ function strOpt(key, domain, get, set) {
33792
+ return str(key, domain, get, set);
33793
+ }
33794
+ function json(key, domain, get, set, extraValidate, editor) {
33795
+ return {
33796
+ key,
33797
+ aliases: [],
33798
+ domain,
33799
+ valueType: "json",
33800
+ reconfigure: false,
33801
+ editor,
33802
+ get,
33803
+ set,
33804
+ extraValidate
33805
+ };
33806
+ }
33807
+ function jsonShape(key, domain, get, set, check, editor) {
33808
+ const extraValidate = (_c, v) => check(v) ? null : "invalid";
33809
+ return json(key, domain, get, set, extraValidate, editor);
33810
+ }
33811
+ function sec(c) {
33812
+ c.security ??= structuredClone(DEFAULT_SECURITY_CONFIG);
33813
+ return c.security;
33814
+ }
33815
+ function isRecord2(v) {
33816
+ return typeof v === "object" && v !== null && !Array.isArray(v);
33817
+ }
33818
+ function isNonNegNum(v) {
33819
+ return typeof v === "number" && Number.isFinite(v) && v >= 0;
33820
+ }
33821
+ var REASONING_BOUNDS, AUDIT_EVENT_TYPES, EXTRA_DEFS;
33822
+ var init_registry_extra = __esm(() => {
33823
+ init_defaults();
33824
+ init_security();
33825
+ REASONING_BOUNDS = ["low", "medium", "high"];
33826
+ AUDIT_EVENT_TYPES = [
33827
+ "security_block",
33828
+ "bash_command",
33829
+ "file_operation",
33830
+ "network_request",
33831
+ "tool_call",
33832
+ "authentication",
33833
+ "configuration_change",
33834
+ "session_start",
33835
+ "session_end"
33836
+ ];
33837
+ EXTRA_DEFS = [
33838
+ bool("provider.fallback", "provider", false, (c) => c.provider.fallback ?? false, (c, v) => {
33839
+ c.provider.fallback = v;
33840
+ }),
33841
+ int("provider.maxCompletionTokens", "provider", 512, 128000, 1024, true, (c) => c.provider.maxCompletionTokens ?? 8192, (c, v) => {
33842
+ c.provider.maxCompletionTokens = v;
33843
+ }),
33844
+ share("contextBudget.compactionThreshold", "budget", false, (c) => c.contextBudget.compactionThreshold, (c, v) => {
33845
+ c.contextBudget.compactionThreshold = v;
33846
+ }),
33847
+ share("contextBudget.compactionMinLoad", "budget", false, (c) => c.contextBudget.compactionMinLoad ?? DEFAULTS.contextBudget.compactionMinLoad, (c, v) => {
33848
+ c.contextBudget.compactionMinLoad = v;
33849
+ }),
33850
+ bool("instructions.summarize", "budget", true, (c) => c.instructions?.summarize ?? DEFAULTS.instructions.summarize, (c, v) => {
33851
+ c.instructions ??= structuredClone(DEFAULTS.instructions);
33852
+ c.instructions.summarize = v;
33853
+ }),
33854
+ bool("contextLog.enabled", "budget", false, (c) => c.contextLog?.enabled ?? DEFAULTS.contextLog.enabled, (c, v) => {
33855
+ c.contextLog ??= structuredClone(DEFAULTS.contextLog);
33856
+ c.contextLog.enabled = v;
33857
+ }),
33858
+ bool("contextLog.redact", "budget", false, (c) => c.contextLog?.redact ?? DEFAULTS.contextLog.redact, (c, v) => {
33859
+ c.contextLog ??= structuredClone(DEFAULTS.contextLog);
33860
+ c.contextLog.redact = v;
33861
+ }),
33862
+ enumOf("reasoning.min", "reasoning", REASONING_BOUNDS, true, (c) => c.reasoning?.min ?? DEFAULTS.reasoning.min, (c, v) => {
33863
+ c.reasoning ??= structuredClone(DEFAULTS.reasoning);
33864
+ c.reasoning.min = v;
33865
+ }),
33866
+ enumOf("reasoning.max", "reasoning", REASONING_BOUNDS, true, (c) => c.reasoning?.max ?? DEFAULTS.reasoning.max, (c, v) => {
33867
+ c.reasoning ??= structuredClone(DEFAULTS.reasoning);
33868
+ c.reasoning.max = v;
33869
+ }),
33870
+ enumOf("reasoning.baseline", "reasoning", REASONING_BOUNDS, true, (c) => c.reasoning?.baseline ?? DEFAULTS.reasoning.baseline, (c, v) => {
33871
+ c.reasoning ??= structuredClone(DEFAULTS.reasoning);
33872
+ c.reasoning.baseline = v;
33873
+ }),
33874
+ int("reasoning.overrideCooldown", "reasoning", 1, 60, 1, true, (c) => c.reasoning?.overrideCooldown ?? DEFAULTS.reasoning.overrideCooldown, (c, v) => {
33875
+ c.reasoning ??= structuredClone(DEFAULTS.reasoning);
33876
+ c.reasoning.overrideCooldown = v;
33877
+ }),
33878
+ bool("autoPlan", "agent", true, (c) => c.autoPlan, (c, v) => {
33879
+ c.autoPlan = v;
33880
+ }),
33881
+ bool("tools.enableOnDemand", "agent", true, (c) => c.tools.enableOnDemand, (c, v) => {
33882
+ c.tools.enableOnDemand = v;
33883
+ }),
33884
+ bool("session.autoSave", "session", false, (c) => c.session?.autoSave ?? DEFAULTS.session.autoSave, (c, v) => {
33885
+ c.session ??= structuredClone(DEFAULTS.session);
33886
+ c.session.autoSave = v;
33887
+ }),
33888
+ int("session.maxSessions", "session", 1, 500, 1, false, (c) => c.session?.maxSessions ?? DEFAULTS.session.maxSessions, (c, v) => {
33889
+ c.session ??= structuredClone(DEFAULTS.session);
33890
+ c.session.maxSessions = v;
33891
+ }),
33892
+ bool("session.isolateMemory", "session", false, (c) => c.session?.isolateMemory ?? DEFAULTS.session.isolateMemory, (c, v) => {
33893
+ c.session ??= structuredClone(DEFAULTS.session);
33894
+ c.session.isolateMemory = v;
33895
+ }),
33896
+ bool("session.autoName", "session", false, (c) => c.session?.autoName ?? DEFAULTS.session.autoName, (c, v) => {
33897
+ c.session ??= structuredClone(DEFAULTS.session);
33898
+ c.session.autoName = v;
33899
+ }),
33900
+ bool("sessionIsolation.enabled", "session", false, (c) => c.sessionIsolation?.enabled ?? DEFAULTS.sessionIsolation.enabled, (c, v) => {
33901
+ c.sessionIsolation ??= structuredClone(DEFAULTS.sessionIsolation);
33902
+ c.sessionIsolation.enabled = v;
33903
+ }),
33904
+ bool("sessionIsolation.isolatePlugins", "session", false, (c) => c.sessionIsolation?.isolatePlugins ?? DEFAULTS.sessionIsolation.isolatePlugins, (c, v) => {
33905
+ c.sessionIsolation ??= structuredClone(DEFAULTS.sessionIsolation);
33906
+ c.sessionIsolation.isolatePlugins = v;
33907
+ }),
33908
+ bool("sessionIsolation.isolateTempFiles", "session", false, (c) => c.sessionIsolation?.isolateTempFiles ?? DEFAULTS.sessionIsolation.isolateTempFiles, (c, v) => {
33909
+ c.sessionIsolation ??= structuredClone(DEFAULTS.sessionIsolation);
33910
+ c.sessionIsolation.isolateTempFiles = v;
33911
+ }),
33912
+ bool("ui.spinner", "ui", false, (c) => c.ui.spinner, (c, v) => {
33913
+ c.ui.spinner = v;
33914
+ }),
33915
+ bool("ui.showContextStats", "ui", false, (c) => c.ui.showContextStats, (c, v) => {
33916
+ c.ui.showContextStats = v;
33917
+ }),
33918
+ bool("ui.showCompaction", "ui", false, (c) => c.ui.showCompaction, (c, v) => {
33919
+ c.ui.showCompaction = v;
33920
+ }),
33921
+ int("retry.maxRetries", "agent", 0, 10, 1, false, (c) => c.retry.maxRetries, (c, v) => {
33922
+ c.retry.maxRetries = v;
33923
+ }),
33924
+ int("retry.baseDelay", "agent", 0, 60000, 100, false, (c) => c.retry.baseDelay, (c, v) => {
33925
+ c.retry.baseDelay = v;
33926
+ }),
33927
+ int("retry.maxDelay", "agent", 0, 300000, 1000, false, (c) => c.retry.maxDelay, (c, v) => {
33928
+ c.retry.maxDelay = v;
33929
+ }),
33930
+ int("retry.maxStreamRetries", "agent", 0, 10, 1, false, (c) => c.retry.maxStreamRetries ?? DEFAULTS.retry.maxStreamRetries, (c, v) => {
33931
+ c.retry.maxStreamRetries = v;
33932
+ }),
33933
+ int("retry.noDataTimeoutMs", "agent", 1000, 600000, 1000, false, (c) => c.retry.noDataTimeoutMs ?? DEFAULTS.retry.noDataTimeoutMs, (c, v) => {
33934
+ c.retry.noDataTimeoutMs = v;
33935
+ }),
33936
+ bool("pricing.enabled", "pricing", false, (c) => c.pricing?.enabled ?? DEFAULTS.pricing.enabled, (c, v) => {
33937
+ c.pricing ??= structuredClone(DEFAULTS.pricing);
33938
+ c.pricing.enabled = v;
33939
+ }),
33940
+ bool("updater.enabled", "updater", false, (c) => c.updater.enabled, (c, v) => {
33941
+ c.updater.enabled = v;
33942
+ }),
33943
+ bool("updater.checkOnStart", "updater", false, (c) => c.updater.checkOnStart, (c, v) => {
33944
+ c.updater.checkOnStart = v;
33945
+ }),
33946
+ bool("updater.autoInstall", "updater", false, (c) => c.updater.autoInstall, (c, v) => {
33947
+ c.updater.autoInstall = v;
33948
+ }),
33949
+ int("updater.intervalMs", "updater", 0, 86400000, 60000, false, (c) => c.updater.intervalMs, (c, v) => {
33950
+ c.updater.intervalMs = v;
33951
+ }),
33952
+ share("skills.budget", "agent", false, (c) => c.skills.budget, (c, v) => {
33953
+ c.skills.budget = v;
33954
+ }),
33955
+ bool("hallucination.judge.enabled", "agent", true, (c) => c.hallucination?.judge.enabled ?? DEFAULTS.hallucination.judge.enabled, (c, v) => {
33956
+ c.hallucination ??= structuredClone(DEFAULTS.hallucination);
33957
+ c.hallucination.judge.enabled = v;
33958
+ }),
33959
+ enumOf("subagent.resultMode", "agent", ["text", "file"], true, (c) => c.subagent?.resultMode ?? DEFAULTS.subagent.resultMode, (c, v) => {
33960
+ c.subagent ??= structuredClone(DEFAULTS.subagent);
33961
+ c.subagent.resultMode = v;
33962
+ }),
33963
+ int("subagent.maxSummaryChars", "agent", 100, 50000, 100, false, (c) => c.subagent?.maxSummaryChars ?? DEFAULTS.subagent.maxSummaryChars, (c, v) => {
33964
+ c.subagent ??= structuredClone(DEFAULTS.subagent);
33965
+ c.subagent.maxSummaryChars = v;
33966
+ }),
33967
+ int("subagent.maxParallelChunkQueries", "agent", 1, 16, 1, false, (c) => c.subagent?.maxParallelChunkQueries ?? DEFAULTS.subagent.maxParallelChunkQueries, (c, v) => {
33968
+ c.subagent ??= structuredClone(DEFAULTS.subagent);
33969
+ c.subagent.maxParallelChunkQueries = v;
33970
+ }),
33971
+ bool("subagent.stableSystemPrompt", "agent", false, (c) => c.subagent?.stableSystemPrompt ?? DEFAULTS.subagent.stableSystemPrompt, (c, v) => {
33972
+ c.subagent ??= structuredClone(DEFAULTS.subagent);
33973
+ c.subagent.stableSystemPrompt = v;
33974
+ }),
33975
+ bool("modelLoad.autoLoad", "provider", true, (c) => c.modelLoad?.autoLoad ?? DEFAULTS.modelLoad.autoLoad, (c, v) => {
33976
+ c.modelLoad ??= structuredClone(DEFAULTS.modelLoad);
33977
+ c.modelLoad.autoLoad = v;
33978
+ }),
33979
+ bool("modelLoad.flashAttention", "provider", true, (c) => c.modelLoad?.flashAttention ?? DEFAULTS.modelLoad.flashAttention, (c, v) => {
33980
+ c.modelLoad ??= structuredClone(DEFAULTS.modelLoad);
33981
+ c.modelLoad.flashAttention = v;
33982
+ }),
33983
+ bool("modelLoad.offloadKvCacheToGpu", "provider", true, (c) => c.modelLoad?.offloadKvCacheToGpu ?? DEFAULTS.modelLoad.offloadKvCacheToGpu, (c, v) => {
33984
+ c.modelLoad ??= structuredClone(DEFAULTS.modelLoad);
33985
+ c.modelLoad.offloadKvCacheToGpu = v;
33986
+ }),
33987
+ int("modelLoad.evalBatchSize", "provider", 1, 4096, 1, true, (c) => c.modelLoad?.evalBatchSize ?? 512, (c, v) => {
33988
+ c.modelLoad ??= structuredClone(DEFAULTS.modelLoad);
33989
+ c.modelLoad.evalBatchSize = v;
33990
+ }),
33991
+ bool("webSearch.enabled", "research", false, (c) => c.webSearch?.enabled ?? DEFAULTS.webSearch.enabled, (c, v) => {
33992
+ c.webSearch ??= structuredClone(DEFAULTS.webSearch);
33993
+ c.webSearch.enabled = v;
33994
+ }),
33995
+ bool("errorWebSearch.enabled", "research", false, (c) => c.errorWebSearch?.enabled ?? DEFAULTS.errorWebSearch.enabled, (c, v) => {
33996
+ c.errorWebSearch ??= structuredClone(DEFAULTS.errorWebSearch);
33997
+ c.errorWebSearch.enabled = v;
33998
+ }),
33999
+ int("errorWebSearch.threshold", "research", 1, 20, 1, false, (c) => c.errorWebSearch?.threshold ?? DEFAULTS.errorWebSearch.threshold, (c, v) => {
34000
+ c.errorWebSearch ??= structuredClone(DEFAULTS.errorWebSearch);
34001
+ c.errorWebSearch.threshold = v;
34002
+ }),
34003
+ int("errorWebSearch.maxResults", "research", 1, 20, 1, false, (c) => c.errorWebSearch?.maxResults ?? DEFAULTS.errorWebSearch.maxResults, (c, v) => {
34004
+ c.errorWebSearch ??= structuredClone(DEFAULTS.errorWebSearch);
34005
+ c.errorWebSearch.maxResults = v;
34006
+ }),
34007
+ int("errorWebSearch.maxQueryChars", "research", 50, 2000, 10, false, (c) => c.errorWebSearch?.maxQueryChars ?? DEFAULTS.errorWebSearch.maxQueryChars, (c, v) => {
34008
+ c.errorWebSearch ??= structuredClone(DEFAULTS.errorWebSearch);
34009
+ c.errorWebSearch.maxQueryChars = v;
34010
+ }),
34011
+ int("errorWebSearch.maxSearchesPerSession", "research", 0, 20, 1, false, (c) => c.errorWebSearch?.maxSearchesPerSession ?? DEFAULTS.errorWebSearch.maxSearchesPerSession, (c, v) => {
34012
+ c.errorWebSearch ??= structuredClone(DEFAULTS.errorWebSearch);
34013
+ c.errorWebSearch.maxSearchesPerSession = v;
34014
+ }),
34015
+ int("errorWebSearch.requestTimeoutMs", "research", 1000, 120000, 1000, false, (c) => c.errorWebSearch?.requestTimeoutMs ?? DEFAULTS.errorWebSearch.requestTimeoutMs, (c, v) => {
34016
+ c.errorWebSearch ??= structuredClone(DEFAULTS.errorWebSearch);
34017
+ c.errorWebSearch.requestTimeoutMs = v;
34018
+ }),
34019
+ bool("browser.enabled", "browser", false, (c) => c.browser.enabled, (c, v) => {
34020
+ c.browser.enabled = v;
34021
+ }),
34022
+ bool("browser.headless", "browser", false, (c) => c.browser.headless, (c, v) => {
34023
+ c.browser.headless = v;
34024
+ }),
34025
+ int("browser.maxElements", "browser", 1, 200, 1, false, (c) => c.browser.maxElements, (c, v) => {
34026
+ c.browser.maxElements = v;
34027
+ }),
34028
+ int("browser.maxContentChars", "browser", 100, 50000, 100, false, (c) => c.browser.maxContentChars, (c, v) => {
34029
+ c.browser.maxContentChars = v;
34030
+ }),
34031
+ int("browser.maxConsoleEntries", "browser", 1, 200, 1, false, (c) => c.browser.maxConsoleEntries, (c, v) => {
34032
+ c.browser.maxConsoleEntries = v;
34033
+ }),
34034
+ int("browser.maxConsoleLineChars", "browser", 50, 5000, 10, false, (c) => c.browser.maxConsoleLineChars, (c, v) => {
34035
+ c.browser.maxConsoleLineChars = v;
34036
+ }),
34037
+ int("browser.viewportWidth", "browser", 320, 4096, 10, false, (c) => c.browser.viewportWidth, (c, v) => {
34038
+ c.browser.viewportWidth = v;
34039
+ }),
34040
+ int("browser.viewportHeight", "browser", 200, 2160, 10, false, (c) => c.browser.viewportHeight, (c, v) => {
34041
+ c.browser.viewportHeight = v;
34042
+ }),
34043
+ int("browser.navigationTimeout", "browser", 1000, 120000, 1000, false, (c) => c.browser.navigationTimeout, (c, v) => {
34044
+ c.browser.navigationTimeout = v;
34045
+ }),
34046
+ int("security.maxRecursionDepth", "security", 0, 20, 1, false, (c) => c.security?.maxRecursionDepth ?? DEFAULT_SECURITY_CONFIG.maxRecursionDepth, (c, v) => {
34047
+ c.security ??= structuredClone(DEFAULT_SECURITY_CONFIG);
34048
+ c.security.maxRecursionDepth = v;
34049
+ }),
34050
+ int("security.maxFileOperations", "security", 0, 1e4, 10, false, (c) => c.security?.maxFileOperations ?? DEFAULT_SECURITY_CONFIG.maxFileOperations, (c, v) => {
34051
+ c.security ??= structuredClone(DEFAULT_SECURITY_CONFIG);
34052
+ c.security.maxFileOperations = v;
34053
+ }),
34054
+ int("security.rateLimits.maxRequestsPerMinute", "security", 1, 1000, 1, false, (c) => c.security?.rateLimits.maxRequestsPerMinute ?? DEFAULT_SECURITY_CONFIG.rateLimits.maxRequestsPerMinute, (c, v) => {
34055
+ c.security ??= structuredClone(DEFAULT_SECURITY_CONFIG);
34056
+ c.security.rateLimits.maxRequestsPerMinute = v;
34057
+ }),
34058
+ int("security.rateLimits.maxParallelTasks", "security", 1, 50, 1, false, (c) => c.security?.rateLimits.maxParallelTasks ?? DEFAULT_SECURITY_CONFIG.rateLimits.maxParallelTasks, (c, v) => {
34059
+ c.security ??= structuredClone(DEFAULT_SECURITY_CONFIG);
34060
+ c.security.rateLimits.maxParallelTasks = v;
34061
+ }),
34062
+ list("tools.defaultTags", "tools", (c) => c.tools.defaultTags, (c, v) => {
34063
+ c.tools.defaultTags = v;
34064
+ }, { kind: "tags", placeholder: "file" }),
34065
+ list("security.bash.blacklist", "security", (c) => c.security?.bash.blacklist ?? DEFAULT_SECURITY_CONFIG.bash.blacklist, (c, v) => {
34066
+ sec(c).bash.blacklist = v;
34067
+ }, { kind: "tags", placeholder: "rm" }),
34068
+ list("security.bash.whitelist", "security", (c) => c.security?.bash.whitelist ?? DEFAULT_SECURITY_CONFIG.bash.whitelist, (c, v) => {
34069
+ sec(c).bash.whitelist = v;
34070
+ }, { kind: "tags", placeholder: "bun" }),
34071
+ list("security.bash.dangerousFlags", "security", (c) => c.security?.bash.dangerousFlags ?? DEFAULT_SECURITY_CONFIG.bash.dangerousFlags, (c, v) => {
34072
+ sec(c).bash.dangerousFlags = v;
34073
+ }, { kind: "tags", placeholder: "--force" }),
34074
+ list("security.bash.dangerousOperators", "security", (c) => c.security?.bash.dangerousOperators ?? DEFAULT_SECURITY_CONFIG.bash.dangerousOperators, (c, v) => {
34075
+ sec(c).bash.dangerousOperators = v;
34076
+ }, { kind: "tags", placeholder: "&&" }),
34077
+ list("security.paths.denied", "security", (c) => c.security?.paths.denied ?? DEFAULT_SECURITY_CONFIG.paths.denied, (c, v) => {
34078
+ sec(c).paths.denied = v;
34079
+ }, { kind: "tags", placeholder: ".git/" }),
34080
+ list("security.paths.allowed", "security", (c) => c.security?.paths.allowed ?? DEFAULT_SECURITY_CONFIG.paths.allowed, (c, v) => {
34081
+ sec(c).paths.allowed = v;
34082
+ }, { kind: "tags", placeholder: "src/**" }),
34083
+ list("security.network.deniedDomains", "security", (c) => c.security?.network.deniedDomains ?? DEFAULT_SECURITY_CONFIG.network.deniedDomains, (c, v) => {
34084
+ sec(c).network.deniedDomains = v;
34085
+ }, { kind: "tags", placeholder: "localhost" }),
34086
+ list("security.network.allowedDomains", "security", (c) => c.security?.network.allowedDomains ?? DEFAULT_SECURITY_CONFIG.network.allowedDomains, (c, v) => {
34087
+ sec(c).network.allowedDomains = v;
34088
+ }, { kind: "tags", placeholder: "api.example.com" }),
34089
+ int("security.network.requestTimeout", "security", 1000, 120000, 1000, false, (c) => c.security?.network.requestTimeout ?? DEFAULT_SECURITY_CONFIG.network.requestTimeout, (c, v) => {
34090
+ sec(c).network.requestTimeout = v;
34091
+ }),
34092
+ int("security.network.maxResponseSize", "security", 1024, 1e6, 1024, false, (c) => c.security?.network.maxResponseSize ?? DEFAULT_SECURITY_CONFIG.network.maxResponseSize, (c, v) => {
34093
+ sec(c).network.maxResponseSize = v;
34094
+ }),
34095
+ jsonShape("security.contentScan.dangerousPatterns", "security", (c) => (c.security?.contentScan.dangerousPatterns ?? DEFAULT_SECURITY_CONFIG.contentScan.dangerousPatterns).map((r) => r.source), (c, v) => {
34096
+ sec(c).contentScan.dangerousPatterns = v.map((s) => new RegExp(s));
34097
+ }, (v) => Array.isArray(v) && v.every((s) => {
34098
+ if (typeof s !== "string")
34099
+ return false;
34100
+ try {
34101
+ new RegExp(s);
34102
+ return true;
34103
+ } catch {
34104
+ return false;
34105
+ }
34106
+ }), { kind: "tags", placeholder: "eval\\(" }),
34107
+ bool("security.auditNotifier.enabled", "security", false, (c) => c.security?.auditNotifier.enabled ?? DEFAULT_SECURITY_CONFIG.auditNotifier.enabled, (c, v) => {
34108
+ sec(c).auditNotifier.enabled = v;
34109
+ }),
34110
+ strOpt("security.auditNotifier.filePath", "security", (c) => c.security?.auditNotifier.filePath ?? "", (c, v) => {
34111
+ const s = String(v).trim();
34112
+ sec(c).auditNotifier.filePath = s.length === 0 ? undefined : s;
34113
+ }),
34114
+ strOpt("security.auditNotifier.webhookUrl", "security", (c) => c.security?.auditNotifier.webhookUrl ?? "", (c, v) => {
34115
+ const s = String(v).trim();
34116
+ sec(c).auditNotifier.webhookUrl = s.length === 0 ? undefined : s;
34117
+ }),
34118
+ int("security.auditNotifier.webhookTimeout", "security", 1000, 60000, 1000, false, (c) => c.security?.auditNotifier.webhookTimeout ?? DEFAULT_SECURITY_CONFIG.auditNotifier.webhookTimeout, (c, v) => {
34119
+ sec(c).auditNotifier.webhookTimeout = v;
34120
+ }),
34121
+ enumOf("security.auditNotifier.minSeverity", "security", ["low", "medium", "high", "critical"], false, (c) => c.security?.auditNotifier.minSeverity ?? DEFAULT_SECURITY_CONFIG.auditNotifier.minSeverity, (c, v) => {
34122
+ sec(c).auditNotifier.minSeverity = v;
34123
+ }),
34124
+ jsonShape("security.auditNotifier.eventTypes", "security", (c) => c.security?.auditNotifier.eventTypes ?? DEFAULT_SECURITY_CONFIG.auditNotifier.eventTypes, (c, v) => {
34125
+ sec(c).auditNotifier.eventTypes = v;
34126
+ }, (v) => Array.isArray(v) && v.every((e) => typeof e === "string" && AUDIT_EVENT_TYPES.includes(e)), { kind: "checkboxes", options: AUDIT_EVENT_TYPES }),
34127
+ int("security.auditNotifier.maxRetries", "security", 0, 10, 1, false, (c) => c.security?.auditNotifier.maxRetries ?? DEFAULT_SECURITY_CONFIG.auditNotifier.maxRetries, (c, v) => {
34128
+ sec(c).auditNotifier.maxRetries = v;
34129
+ }),
34130
+ strOpt("security.sessionEncryption.keyPath", "security", (c) => c.security?.sessionEncryption.keyPath ?? "", (c, v) => {
34131
+ const s = String(v).trim();
34132
+ sec(c).sessionEncryption.keyPath = s.length === 0 ? undefined : s;
34133
+ }),
34134
+ bool("security.sessionEncryption.encryptHistory", "security", false, (c) => c.security?.sessionEncryption.encryptHistory ?? DEFAULT_SECURITY_CONFIG.sessionEncryption.encryptHistory, (c, v) => {
34135
+ sec(c).sessionEncryption.encryptHistory = v;
34136
+ }),
34137
+ bool("security.sessionEncryption.encryptSessionLog", "security", false, (c) => c.security?.sessionEncryption.encryptSessionLog ?? DEFAULT_SECURITY_CONFIG.sessionEncryption.encryptSessionLog, (c, v) => {
34138
+ sec(c).sessionEncryption.encryptSessionLog = v;
34139
+ }),
34140
+ jsonShape("pricing.overrides", "pricing", (c) => c.pricing?.overrides ?? {}, (c, v) => {
34141
+ c.pricing ??= structuredClone(DEFAULTS.pricing);
34142
+ c.pricing.overrides = v;
34143
+ }, (v) => isRecord2(v) && Object.values(v).every((e) => isRecord2(e) && isNonNegNum(e.input) && isNonNegNum(e.output) && (e.cachedInput === undefined || isNonNegNum(e.cachedInput)) && (e.cacheWrite === undefined || isNonNegNum(e.cacheWrite))), {
34144
+ kind: "table",
34145
+ columns: [
34146
+ { key: "name" },
34147
+ { key: "input", type: "number" },
34148
+ { key: "output", type: "number" },
34149
+ { key: "cachedInput", type: "number", optional: true },
34150
+ { key: "cacheWrite", type: "number", optional: true }
34151
+ ]
34152
+ }),
34153
+ jsonShape("modelCapabilities", "provider", (c) => c.modelCapabilities ?? {}, (c, v) => {
34154
+ c.modelCapabilities = v;
34155
+ }, (v) => isRecord2(v) && Object.values(v).every((e) => isRecord2(e) && (e.vision === undefined || typeof e.vision === "boolean") && (e.tools === undefined || typeof e.tools === "boolean")), {
34156
+ kind: "table",
34157
+ columns: [
34158
+ { key: "name" },
34159
+ { key: "vision", type: "bool", optional: true },
34160
+ { key: "tools", type: "bool", optional: true }
34161
+ ]
34162
+ }),
34163
+ jsonShape("experts", "agent", (c) => c.experts, (c, v) => {
34164
+ c.experts = v;
34165
+ }, (v) => isRecord2(v) && Object.values(v).every((e) => isRecord2(e) && typeof e.model === "string" && Array.isArray(e.tool_tags) && e.tool_tags.every((t2) => typeof t2 === "string") && (e.max_attempts === undefined || typeof e.max_attempts === "number" && Number.isFinite(e.max_attempts)) && (e.description === undefined || typeof e.description === "string")), {
34166
+ kind: "table",
34167
+ columns: [
34168
+ { key: "name" },
34169
+ { key: "model" },
34170
+ { key: "tool_tags", array: true },
34171
+ { key: "max_attempts", type: "number", optional: true },
34172
+ { key: "description", optional: true }
34173
+ ]
34174
+ })
34175
+ ];
34176
+ });
34177
+
34178
+ // src/config/registry.ts
34179
+ function shareField(key, canonical) {
34180
+ const field = key === "system" ? "systemPrompt" : "responseReserve";
34181
+ const other = key === "system" ? "responseReserve" : "systemPrompt";
34182
+ return {
34183
+ key: canonical,
34184
+ aliases: [`context.${key}`],
34185
+ domain: "budget",
34186
+ valueType: "share",
34187
+ min: MIN_SHARE2,
34188
+ max: MAX_SHARE2,
34189
+ step: 0.01,
34190
+ reconfigure: true,
34191
+ get: (c) => c.contextBudget[field],
34192
+ set: (c, v) => setBudgetShare(c, key, v),
34193
+ extraValidate: (c, v) => {
34194
+ const n = v;
34195
+ const total = n + c.contextBudget[other];
34196
+ return total > MAX_COMBINED2 ? "combined" : null;
34197
+ }
34198
+ };
34199
+ }
34200
+ function securityToggle(field, canonical) {
34201
+ return {
34202
+ key: canonical,
34203
+ aliases: [],
34204
+ domain: "security",
34205
+ valueType: "bool",
34206
+ reconfigure: false,
34207
+ get: (c) => {
34208
+ const sec2 = c.security;
34209
+ if (!sec2)
34210
+ return false;
34211
+ return field === "enabled" ? sec2.enabled : sec2[field].enabled;
34212
+ },
34213
+ set: (c, v) => {
34214
+ if (!c.security)
34215
+ c.security = structuredClone(DEFAULT_SECURITY_CONFIG);
34216
+ if (field === "enabled")
34217
+ c.security.enabled = v;
34218
+ else
34219
+ c.security[field].enabled = v;
34220
+ }
34221
+ };
34222
+ }
34223
+ function resolveConfigKey(name) {
34224
+ return BY_NAME.get(name) ?? null;
34225
+ }
34226
+ function configDefs() {
34227
+ return DEFINITIONS;
34228
+ }
34229
+ function canonicalKeys() {
34230
+ return DEFINITIONS.map((d) => d.key);
34231
+ }
34232
+ function keysForGroup(prefix) {
34233
+ return DEFINITIONS.filter((d) => d.key.startsWith(`${prefix}.`));
34234
+ }
34235
+ function allConfigNames() {
34236
+ const out = [];
34237
+ for (const def of DEFINITIONS) {
34238
+ out.push({ name: def.key, def, alias: false });
34239
+ for (const a of def.aliases)
34240
+ out.push({ name: a, def, alias: true });
34241
+ }
34242
+ return out;
34243
+ }
34244
+ function formatConfigValue(value) {
34245
+ if (typeof value === "boolean")
34246
+ return value ? "on" : "off";
34247
+ if (Array.isArray(value))
34248
+ return value.join(", ");
34249
+ if (typeof value === "object" && value !== null)
34250
+ return JSON.stringify(value);
34251
+ return String(value);
34252
+ }
34253
+ function parseBool(raw) {
34254
+ const v = raw.trim().toLowerCase();
34255
+ if (["on", "true", "1", "yes", "y", "enable", "enabled"].includes(v))
34256
+ return { ok: true, value: true };
34257
+ if (["off", "false", "0", "no", "n", "disable", "disabled"].includes(v))
34258
+ return { ok: true, value: false };
34259
+ return { ok: false, reason: "invalid" };
34260
+ }
34261
+ function parseConfigValue(def, raw) {
34262
+ const trimmed = raw.trim();
34263
+ switch (def.valueType) {
34264
+ case "string":
34265
+ return trimmed.length > 0 ? { ok: true, value: trimmed } : { ok: false, reason: "invalid" };
34266
+ case "bool":
34267
+ return parseBool(trimmed);
34268
+ case "enum": {
34269
+ const v = trimmed.toLowerCase();
34270
+ if (def.enumValues && !def.enumValues.includes(v))
34271
+ return { ok: false, reason: "invalid" };
34272
+ return { ok: true, value: v };
34273
+ }
34274
+ case "int": {
34275
+ if (!/^-?\d+$/.test(trimmed))
34276
+ return { ok: false, reason: "invalid" };
34277
+ const n = Number(trimmed);
34278
+ if (!Number.isFinite(n))
34279
+ return { ok: false, reason: "invalid" };
34280
+ if (def.min !== undefined && n < def.min)
34281
+ return { ok: false, reason: "invalid" };
34282
+ if (def.max !== undefined && n > def.max)
34283
+ return { ok: false, reason: "invalid" };
34284
+ return { ok: true, value: n };
34285
+ }
34286
+ case "share": {
34287
+ const isPct = trimmed.endsWith("%");
34288
+ const body = isPct ? trimmed.slice(0, -1).trim() : trimmed;
34289
+ if (!/^-?\d+(\.\d+)?$/.test(body))
34290
+ return { ok: false, reason: "invalid" };
34291
+ let n = Number(body);
34292
+ if (isPct)
34293
+ n = n / 100;
34294
+ if (!Number.isFinite(n) || n < MIN_SHARE2 || n > MAX_SHARE2)
34295
+ return { ok: false, reason: "invalid" };
34296
+ return { ok: true, value: n };
34297
+ }
34298
+ case "list": {
34299
+ if (trimmed.length === 0)
34300
+ return { ok: true, value: [] };
34301
+ if (trimmed.startsWith("[")) {
34302
+ try {
34303
+ const parsed = JSON.parse(trimmed);
34304
+ if (Array.isArray(parsed) && parsed.every((x) => typeof x === "string")) {
34305
+ return { ok: true, value: parsed };
34306
+ }
34307
+ } catch {}
34308
+ }
34309
+ const items = trimmed.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
34310
+ return { ok: true, value: items };
34311
+ }
34312
+ case "json": {
34313
+ if (trimmed.length > 20000)
34314
+ return { ok: false, reason: "invalid" };
34315
+ try {
34316
+ return { ok: true, value: JSON.parse(trimmed) };
34317
+ } catch {
34318
+ return { ok: false, reason: "invalid" };
34319
+ }
34320
+ }
34321
+ }
34322
+ }
34323
+ function getConfigValue(config, name) {
34324
+ const def = resolveConfigKey(name);
34325
+ if (!def)
34326
+ return { ok: false, reason: "unknown-key", input: name };
34327
+ const value = def.get(config);
34328
+ return { ok: true, key: def.key, def, value, display: formatConfigValue(value) };
34329
+ }
34330
+ function applyProviderModelMemory(config, key, value) {
34331
+ const provider = config.provider;
34332
+ const activeName = provider.active ?? provider.type;
34333
+ if (key === "model") {
34334
+ if (!activeName)
34335
+ return;
34336
+ provider.models = { ...provider.models ?? {}, [activeName]: String(value) };
34337
+ return;
34338
+ }
34339
+ if (key === "provider.active") {
34340
+ const remembered = provider.models?.[String(value)];
34341
+ if (remembered)
34342
+ config.model = remembered;
34343
+ }
34344
+ }
34345
+ function setConfigValue(config, name, raw) {
34346
+ const def = resolveConfigKey(name);
34347
+ if (!def)
34348
+ return { ok: false, reason: "unknown-key", input: name };
34349
+ if (def.readOnly)
34350
+ return { ok: false, reason: "read-only", input: name, key: def.key, def };
34351
+ const parsed = parseConfigValue(def, raw);
34352
+ if (!parsed.ok)
34353
+ return { ok: false, reason: "invalid-value", input: name, key: def.key, def };
34354
+ const extra = def.extraValidate?.(config, parsed.value);
34355
+ if (extra)
34356
+ return { ok: false, reason: extra, input: name, key: def.key, def };
34357
+ def.set(config, parsed.value);
34358
+ applyProviderModelMemory(config, def.key, parsed.value);
34359
+ return {
34360
+ ok: true,
34361
+ key: def.key,
34362
+ def,
34363
+ value: parsed.value,
34364
+ display: formatConfigValue(parsed.value),
34365
+ reconfigure: def.reconfigure,
34366
+ reasoningChanged: def.key === "reasoning.mode"
34367
+ };
34368
+ }
34369
+ function captureConfigSnapshot(config) {
34370
+ const snapshot = new Map;
34371
+ for (const def of DEFINITIONS) {
34372
+ try {
34373
+ snapshot.set(def.key, structuredClone(def.get(config)));
34374
+ } catch {}
34375
+ }
34376
+ return snapshot;
34377
+ }
34378
+ var REASONING_LEVELS, LOG_LEVELS, VERBOSITY_LEVELS, LOCALES, MIN_SHARE2 = 0.05, MAX_SHARE2 = 0.9, MAX_COMBINED2 = 0.95, DEFINITIONS, BY_NAME;
34379
+ var init_registry2 = __esm(() => {
34380
+ init_defaults();
34381
+ init_security();
34382
+ init_budget();
34383
+ init_version();
34384
+ init_registry_extra();
34385
+ REASONING_LEVELS = [
34386
+ "auto",
34387
+ "default",
34388
+ "none",
34389
+ "low",
34390
+ "medium",
34391
+ "high",
34392
+ "max"
34393
+ ];
34394
+ LOG_LEVELS = ["silent", "error", "warn", "info", "debug"];
34395
+ VERBOSITY_LEVELS = ["quiet", "normal", "verbose"];
34396
+ LOCALES = ["en", "ru"];
34397
+ DEFINITIONS = [
34398
+ {
34399
+ key: "model",
34400
+ aliases: [],
34401
+ domain: "agent",
34402
+ valueType: "string",
34403
+ reconfigure: true,
34404
+ get: (c) => c.model,
34405
+ set: (c, v) => {
34406
+ c.model = String(v);
34407
+ }
34408
+ },
34409
+ {
34410
+ key: "provider.active",
34411
+ aliases: [],
34412
+ domain: "provider",
34413
+ valueType: "string",
34414
+ reconfigure: true,
34415
+ get: (c) => c.provider.active ?? c.provider.type,
34416
+ set: (c, v) => {
34417
+ c.provider.active = String(v);
34418
+ },
34419
+ extraValidate: (c, v) => {
34420
+ const entries = c.provider.entries ?? [];
34421
+ if (entries.length === 0)
34422
+ return null;
34423
+ const name = String(v);
34424
+ const found = entries.some((e) => e.label === name || e.type === name);
34425
+ return found ? null : "invalid";
34426
+ }
34427
+ },
34428
+ {
34429
+ key: "contextWindow",
34430
+ aliases: ["context.window"],
34431
+ domain: "budget",
34432
+ valueType: "int",
34433
+ min: 1024,
34434
+ step: 1024,
34435
+ reconfigure: true,
34436
+ get: (c) => c.contextWindow,
34437
+ set: (c, v) => {
34438
+ c.contextWindow = v;
34439
+ }
34440
+ },
34441
+ shareField("system", "contextBudget.systemPrompt"),
34442
+ shareField("reserve", "contextBudget.responseReserve"),
34443
+ {
34444
+ key: "showReasoning",
34445
+ aliases: ["reasoning.show"],
34446
+ domain: "reasoning",
34447
+ valueType: "bool",
34448
+ reconfigure: false,
34449
+ get: (c) => c.showReasoning,
34450
+ set: (c, v) => {
34451
+ c.showReasoning = v;
34452
+ }
34453
+ },
34454
+ {
34455
+ key: "reasoning.mode",
34456
+ aliases: ["reasoning.level"],
34457
+ domain: "reasoning",
34458
+ valueType: "enum",
34459
+ enumValues: REASONING_LEVELS,
34460
+ reconfigure: true,
34461
+ get: (c) => c.reasoning?.mode ?? "auto",
34462
+ set: (c, v) => {
34463
+ const base = c.reasoning ?? structuredClone(DEFAULTS.reasoning);
34464
+ c.reasoning = { ...base, mode: v };
34465
+ }
34466
+ },
34467
+ {
34468
+ key: "ui.verbosity",
34469
+ aliases: ["verbosity"],
34470
+ domain: "ui",
34471
+ valueType: "enum",
34472
+ enumValues: VERBOSITY_LEVELS,
34473
+ reconfigure: false,
34474
+ get: (c) => c.ui.verbosity ?? (c.ui.verbose ? "verbose" : "quiet"),
34475
+ set: (c, v) => {
34476
+ c.ui.verbosity = v;
34477
+ }
34478
+ },
34479
+ {
34480
+ key: "maxToolIterations",
34481
+ aliases: [],
34482
+ domain: "agent",
34483
+ valueType: "int",
34484
+ min: 1,
34485
+ step: 1,
34486
+ reconfigure: false,
34487
+ get: (c) => c.maxToolIterations,
34488
+ set: (c, v) => {
34489
+ c.maxToolIterations = v;
34490
+ }
34491
+ },
34492
+ {
34493
+ key: "stuckThreshold",
34494
+ aliases: [],
34495
+ domain: "agent",
34496
+ valueType: "int",
34497
+ min: 1,
34498
+ step: 1,
34499
+ reconfigure: false,
34500
+ get: (c) => c.stuckThreshold,
34501
+ set: (c, v) => {
34502
+ c.stuckThreshold = v;
34503
+ }
34504
+ },
34505
+ {
34506
+ key: "moe.enabled",
34507
+ aliases: [],
34508
+ domain: "agent",
34509
+ valueType: "bool",
34510
+ reconfigure: true,
34511
+ get: (c) => c.moe?.enabled ?? DEFAULTS.moe.enabled,
34512
+ set: (c, v) => {
34513
+ c.moe = { ...c.moe ?? DEFAULTS.moe, enabled: v };
34514
+ }
34515
+ },
34516
+ {
34517
+ key: "moe.maxReplanCycles",
34518
+ aliases: [],
34519
+ domain: "agent",
34520
+ valueType: "int",
34521
+ min: 0,
34522
+ max: 10,
34523
+ step: 1,
34524
+ reconfigure: true,
34525
+ get: (c) => c.moe?.maxReplanCycles ?? DEFAULTS.moe.maxReplanCycles,
34526
+ set: (c, v) => {
34527
+ c.moe = { ...c.moe ?? DEFAULTS.moe, maxReplanCycles: v };
34528
+ }
34529
+ },
34530
+ {
34531
+ key: "critic.enabled",
34532
+ aliases: [],
34533
+ domain: "agent",
34534
+ valueType: "bool",
34535
+ reconfigure: true,
34536
+ get: (c) => c.critic?.enabled ?? DEFAULTS.critic.enabled,
34537
+ set: (c, v) => {
34538
+ c.critic = { ...c.critic ?? DEFAULTS.critic, enabled: v };
34539
+ }
34540
+ },
34541
+ {
34542
+ key: "critic.maxCalls",
34543
+ aliases: [],
34544
+ domain: "agent",
34545
+ valueType: "int",
34546
+ min: 0,
34547
+ max: 20,
34548
+ step: 1,
34549
+ reconfigure: true,
34550
+ get: (c) => c.critic?.maxCalls ?? DEFAULTS.critic.maxCalls,
34551
+ set: (c, v) => {
34552
+ c.critic = { ...c.critic ?? DEFAULTS.critic, maxCalls: v };
34553
+ }
34554
+ },
34555
+ {
34556
+ key: "critic.maxRepairCycles",
34557
+ aliases: [],
34558
+ domain: "agent",
34559
+ valueType: "int",
34560
+ min: 0,
34561
+ max: 5,
34562
+ step: 1,
34563
+ reconfigure: true,
34564
+ get: (c) => c.critic?.maxRepairCycles ?? DEFAULTS.critic.maxRepairCycles,
34565
+ set: (c, v) => {
34566
+ c.critic = { ...c.critic ?? DEFAULTS.critic, maxRepairCycles: v };
34567
+ }
34568
+ },
34569
+ {
34570
+ key: "critic.timeoutMs",
34571
+ aliases: [],
34572
+ domain: "agent",
34573
+ valueType: "int",
34574
+ min: 1000,
34575
+ max: 120000,
34576
+ step: 1000,
34577
+ reconfigure: true,
34578
+ get: (c) => c.critic?.timeoutMs ?? DEFAULTS.critic.timeoutMs,
34579
+ set: (c, v) => {
34580
+ c.critic = { ...c.critic ?? DEFAULTS.critic, timeoutMs: v };
34581
+ }
34582
+ },
34583
+ {
34584
+ key: "logLevel",
34585
+ aliases: [],
34586
+ domain: "agent",
34587
+ valueType: "enum",
34588
+ enumValues: LOG_LEVELS,
34589
+ reconfigure: false,
34590
+ get: (c) => c.logLevel,
34591
+ set: (c, v) => {
34592
+ c.logLevel = String(v);
34593
+ }
34594
+ },
34595
+ {
34596
+ key: "locale",
34597
+ aliases: [],
34598
+ domain: "i18n",
34599
+ valueType: "enum",
34600
+ enumValues: LOCALES,
34601
+ reconfigure: false,
34602
+ get: (c) => c.locale,
34603
+ set: (c, v) => {
34604
+ c.locale = String(v);
34605
+ }
34606
+ },
34607
+ {
34608
+ key: "version",
34609
+ aliases: [],
34610
+ domain: "agent",
34611
+ valueType: "string",
34612
+ reconfigure: false,
34613
+ readOnly: true,
34614
+ get: () => readMmaVersion()
34615
+ },
34616
+ securityToggle("enabled", "security.enabled"),
34617
+ securityToggle("bash", "security.bash.enabled"),
34618
+ {
34619
+ key: "security.bash.blockDangerousFlags",
34620
+ aliases: [],
34621
+ domain: "security",
34622
+ valueType: "bool",
34623
+ reconfigure: false,
34624
+ get: (c) => c.security?.bash.blockDangerousFlags ?? true,
34625
+ set: (c, v) => {
34626
+ if (!c.security)
34627
+ c.security = structuredClone(DEFAULT_SECURITY_CONFIG);
34628
+ c.security.bash.blockDangerousFlags = v;
34629
+ }
34630
+ },
34631
+ securityToggle("paths", "security.paths.enabled"),
34632
+ securityToggle("contentScan", "security.contentScan.enabled"),
34633
+ securityToggle("sessionEncryption", "security.sessionEncryption.enabled"),
34634
+ securityToggle("network", "security.network.enabled"),
34635
+ ...EXTRA_DEFS
34636
+ ];
34637
+ BY_NAME = new Map;
34638
+ for (const def of DEFINITIONS) {
34639
+ BY_NAME.set(def.key, def);
34640
+ for (const alias of def.aliases)
34641
+ BY_NAME.set(alias, def);
34642
+ }
34643
+ });
34644
+
33174
34645
  // node_modules/yaml/dist/nodes/identity.js
33175
34646
  var require_identity = __commonJS((exports) => {
33176
34647
  var ALIAS = Symbol.for("yaml.alias");
@@ -34032,16 +35503,16 @@ var require_Collection = __commonJS((exports) => {
34032
35503
 
34033
35504
  // node_modules/yaml/dist/stringify/stringifyComment.js
34034
35505
  var require_stringifyComment = __commonJS((exports) => {
34035
- var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
35506
+ var stringifyComment = (str2) => str2.replace(/^(?!$)(?: $)?/gm, "#");
34036
35507
  function indentComment(comment, indent) {
34037
35508
  if (/^\n+$/.test(comment))
34038
35509
  return comment.substring(1);
34039
35510
  return indent ? comment.replace(/^(?! *$)/gm, indent) : comment;
34040
35511
  }
34041
- var lineComment = (str, indent, comment) => str.endsWith(`
35512
+ var lineComment = (str2, indent, comment) => str2.endsWith(`
34042
35513
  `) ? indentComment(comment, indent) : comment.includes(`
34043
35514
  `) ? `
34044
- ` + indentComment(comment, indent) : (str.endsWith(" ") ? "" : " ") + comment;
35515
+ ` + indentComment(comment, indent) : (str2.endsWith(" ") ? "" : " ") + comment;
34045
35516
  exports.indentComment = indentComment;
34046
35517
  exports.lineComment = lineComment;
34047
35518
  exports.stringifyComment = stringifyComment;
@@ -34193,16 +35664,16 @@ var require_stringifyString = __commonJS((exports) => {
34193
35664
  lineWidth: ctx.options.lineWidth,
34194
35665
  minContentWidth: ctx.options.minContentWidth
34195
35666
  });
34196
- var containsDocumentMarker = (str) => /^(%|---|\.\.\.)/m.test(str);
34197
- function lineLengthOverLimit(str, lineWidth, indentLength) {
35667
+ var containsDocumentMarker = (str2) => /^(%|---|\.\.\.)/m.test(str2);
35668
+ function lineLengthOverLimit(str2, lineWidth, indentLength) {
34198
35669
  if (!lineWidth || lineWidth < 0)
34199
35670
  return false;
34200
35671
  const limit = lineWidth - indentLength;
34201
- const strLen = str.length;
35672
+ const strLen = str2.length;
34202
35673
  if (strLen <= limit)
34203
35674
  return false;
34204
35675
  for (let i = 0, start = 0;i < strLen; ++i) {
34205
- if (str[i] === `
35676
+ if (str2[i] === `
34206
35677
  `) {
34207
35678
  if (i - start > limit)
34208
35679
  return true;
@@ -34214,77 +35685,77 @@ var require_stringifyString = __commonJS((exports) => {
34214
35685
  return true;
34215
35686
  }
34216
35687
  function doubleQuotedString(value, ctx) {
34217
- const json = JSON.stringify(value);
35688
+ const json2 = JSON.stringify(value);
34218
35689
  if (ctx.options.doubleQuotedAsJSON)
34219
- return json;
35690
+ return json2;
34220
35691
  const { implicitKey } = ctx;
34221
35692
  const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;
34222
35693
  const indent = ctx.indent || (containsDocumentMarker(value) ? " " : "");
34223
- let str = "";
35694
+ let str2 = "";
34224
35695
  let start = 0;
34225
- for (let i = 0, ch = json[i];ch; ch = json[++i]) {
34226
- if (ch === " " && json[i + 1] === "\\" && json[i + 2] === "n") {
34227
- str += json.slice(start, i) + "\\ ";
35696
+ for (let i = 0, ch = json2[i];ch; ch = json2[++i]) {
35697
+ if (ch === " " && json2[i + 1] === "\\" && json2[i + 2] === "n") {
35698
+ str2 += json2.slice(start, i) + "\\ ";
34228
35699
  i += 1;
34229
35700
  start = i;
34230
35701
  ch = "\\";
34231
35702
  }
34232
35703
  if (ch === "\\")
34233
- switch (json[i + 1]) {
35704
+ switch (json2[i + 1]) {
34234
35705
  case "u":
34235
35706
  {
34236
- str += json.slice(start, i);
34237
- const code = json.substr(i + 2, 4);
35707
+ str2 += json2.slice(start, i);
35708
+ const code = json2.substr(i + 2, 4);
34238
35709
  switch (code) {
34239
35710
  case "0000":
34240
- str += "\\0";
35711
+ str2 += "\\0";
34241
35712
  break;
34242
35713
  case "0007":
34243
- str += "\\a";
35714
+ str2 += "\\a";
34244
35715
  break;
34245
35716
  case "000b":
34246
- str += "\\v";
35717
+ str2 += "\\v";
34247
35718
  break;
34248
35719
  case "001b":
34249
- str += "\\e";
35720
+ str2 += "\\e";
34250
35721
  break;
34251
35722
  case "0085":
34252
- str += "\\N";
35723
+ str2 += "\\N";
34253
35724
  break;
34254
35725
  case "00a0":
34255
- str += "\\_";
35726
+ str2 += "\\_";
34256
35727
  break;
34257
35728
  case "2028":
34258
- str += "\\L";
35729
+ str2 += "\\L";
34259
35730
  break;
34260
35731
  case "2029":
34261
- str += "\\P";
35732
+ str2 += "\\P";
34262
35733
  break;
34263
35734
  default:
34264
35735
  if (code.substr(0, 2) === "00")
34265
- str += "\\x" + code.substr(2);
35736
+ str2 += "\\x" + code.substr(2);
34266
35737
  else
34267
- str += json.substr(i, 6);
35738
+ str2 += json2.substr(i, 6);
34268
35739
  }
34269
35740
  i += 5;
34270
35741
  start = i + 1;
34271
35742
  }
34272
35743
  break;
34273
35744
  case "n":
34274
- if (implicitKey || json[i + 2] === '"' || json.length < minMultiLineLength) {
35745
+ if (implicitKey || json2[i + 2] === '"' || json2.length < minMultiLineLength) {
34275
35746
  i += 1;
34276
35747
  } else {
34277
- str += json.slice(start, i) + `
35748
+ str2 += json2.slice(start, i) + `
34278
35749
 
34279
35750
  `;
34280
- while (json[i + 2] === "\\" && json[i + 3] === "n" && json[i + 4] !== '"') {
34281
- str += `
35751
+ while (json2[i + 2] === "\\" && json2[i + 3] === "n" && json2[i + 4] !== '"') {
35752
+ str2 += `
34282
35753
  `;
34283
35754
  i += 2;
34284
35755
  }
34285
- str += indent;
34286
- if (json[i + 2] === " ")
34287
- str += "\\";
35756
+ str2 += indent;
35757
+ if (json2[i + 2] === " ")
35758
+ str2 += "\\";
34288
35759
  i += 1;
34289
35760
  start = i + 1;
34290
35761
  }
@@ -34293,8 +35764,8 @@ var require_stringifyString = __commonJS((exports) => {
34293
35764
  i += 1;
34294
35765
  }
34295
35766
  }
34296
- str = start ? str + json.slice(start) : json;
34297
- return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
35767
+ str2 = start ? str2 + json2.slice(start) : json2;
35768
+ return implicitKey ? str2 : foldFlowLines.foldFlowLines(str2, indent, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
34298
35769
  }
34299
35770
  function singleQuotedString(value, ctx) {
34300
35771
  if (ctx.options.singleQuote === false || ctx.implicitKey && value.includes(`
@@ -34436,15 +35907,15 @@ ${indent}${start}${value}${end}`;
34436
35907
  return quotedString(value, ctx);
34437
35908
  }
34438
35909
  }
34439
- const str = value.replace(/\n+/g, `$&
35910
+ const str2 = value.replace(/\n+/g, `$&
34440
35911
  ${indent}`);
34441
35912
  if (actualString) {
34442
- const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str);
35913
+ const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str2);
34443
35914
  const { compat, tags } = ctx.doc.schema;
34444
35915
  if (tags.some(test) || compat?.some(test))
34445
35916
  return quotedString(value, ctx);
34446
35917
  }
34447
- return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
35918
+ return implicitKey ? str2 : foldFlowLines.foldFlowLines(str2, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
34448
35919
  }
34449
35920
  function stringifyString(item, ctx, onComment, onChompKeep) {
34450
35921
  const { implicitKey, inFlow } = ctx;
@@ -34593,11 +36064,11 @@ var require_stringify = __commonJS((exports) => {
34593
36064
  const props = stringifyProps(node, tagObj, ctx);
34594
36065
  if (props.length > 0)
34595
36066
  ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;
34596
- const str = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : identity.isScalar(node) ? stringifyString.stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep);
36067
+ const str2 = typeof tagObj.stringify === "function" ? tagObj.stringify(node, ctx, onComment, onChompKeep) : identity.isScalar(node) ? stringifyString.stringifyString(node, ctx, onComment, onChompKeep) : node.toString(ctx, onComment, onChompKeep);
34597
36068
  if (!props)
34598
- return str;
34599
- return identity.isScalar(node) || str[0] === "{" || str[0] === "[" ? `${props} ${str}` : `${props}
34600
- ${ctx.indent}${str}`;
36069
+ return str2;
36070
+ return identity.isScalar(node) || str2[0] === "{" || str2[0] === "[" ? `${props} ${str2}` : `${props}
36071
+ ${ctx.indent}${str2}`;
34601
36072
  }
34602
36073
  exports.createStringifyContext = createStringifyContext;
34603
36074
  exports.stringify = stringify;
@@ -34629,8 +36100,8 @@ var require_stringifyPair = __commonJS((exports) => {
34629
36100
  });
34630
36101
  let keyCommentDone = false;
34631
36102
  let chompKeep = false;
34632
- let str = stringify.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
34633
- if (!explicitKey && !ctx.inFlow && str.length > 1024) {
36103
+ let str2 = stringify.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
36104
+ if (!explicitKey && !ctx.inFlow && str2.length > 1024) {
34634
36105
  if (simpleKeys)
34635
36106
  throw new Error("With simple keys, single line scalar must not span more than 1024 characters");
34636
36107
  explicitKey = true;
@@ -34639,27 +36110,27 @@ var require_stringifyPair = __commonJS((exports) => {
34639
36110
  if (allNullValues || value == null) {
34640
36111
  if (keyCommentDone && onComment)
34641
36112
  onComment();
34642
- return str === "" ? "?" : explicitKey ? `? ${str}` : str;
36113
+ return str2 === "" ? "?" : explicitKey ? `? ${str2}` : str2;
34643
36114
  }
34644
36115
  } else if (allNullValues && !simpleKeys || value == null && explicitKey) {
34645
- str = `? ${str}`;
36116
+ str2 = `? ${str2}`;
34646
36117
  if (keyComment && !keyCommentDone) {
34647
- str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
36118
+ str2 += stringifyComment.lineComment(str2, ctx.indent, commentString(keyComment));
34648
36119
  } else if (chompKeep && onChompKeep)
34649
36120
  onChompKeep();
34650
- return str;
36121
+ return str2;
34651
36122
  }
34652
36123
  if (keyCommentDone)
34653
36124
  keyComment = null;
34654
36125
  if (explicitKey) {
34655
36126
  if (keyComment)
34656
- str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
34657
- str = `? ${str}
36127
+ str2 += stringifyComment.lineComment(str2, ctx.indent, commentString(keyComment));
36128
+ str2 = `? ${str2}
34658
36129
  ${indent}:`;
34659
36130
  } else {
34660
- str = `${str}:`;
36131
+ str2 = `${str2}:`;
34661
36132
  if (keyComment)
34662
- str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
36133
+ str2 += stringifyComment.lineComment(str2, ctx.indent, commentString(keyComment));
34663
36134
  }
34664
36135
  let vsb, vcb, valueComment;
34665
36136
  if (identity.isNode(value)) {
@@ -34675,7 +36146,7 @@ ${indent}:`;
34675
36146
  }
34676
36147
  ctx.implicitKey = false;
34677
36148
  if (!explicitKey && !keyComment && identity.isScalar(value))
34678
- ctx.indentAtStart = str.length + 1;
36149
+ ctx.indentAtStart = str2.length + 1;
34679
36150
  chompKeep = false;
34680
36151
  if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && identity.isSeq(value) && !value.flow && !value.tag && !value.anchor) {
34681
36152
  ctx.indent = ctx.indent.substring(2);
@@ -34725,16 +36196,16 @@ ${ctx.indent}`;
34725
36196
  `) {
34726
36197
  ws = "";
34727
36198
  }
34728
- str += ws + valueStr;
36199
+ str2 += ws + valueStr;
34729
36200
  if (ctx.inFlow) {
34730
36201
  if (valueCommentDone && onComment)
34731
36202
  onComment();
34732
36203
  } else if (valueComment && !valueCommentDone) {
34733
- str += stringifyComment.lineComment(str, ctx.indent, commentString(valueComment));
36204
+ str2 += stringifyComment.lineComment(str2, ctx.indent, commentString(valueComment));
34734
36205
  } else if (chompKeep && onChompKeep) {
34735
36206
  onChompKeep();
34736
36207
  }
34737
- return str;
36208
+ return str2;
34738
36209
  }
34739
36210
  exports.stringifyPair = stringifyPair;
34740
36211
  });
@@ -34947,33 +36418,33 @@ var require_stringifyCollection = __commonJS((exports) => {
34947
36418
  }
34948
36419
  }
34949
36420
  chompKeep = false;
34950
- let str2 = stringify.stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true);
36421
+ let str3 = stringify.stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true);
34951
36422
  if (comment2)
34952
- str2 += stringifyComment.lineComment(str2, itemIndent, commentString(comment2));
36423
+ str3 += stringifyComment.lineComment(str3, itemIndent, commentString(comment2));
34953
36424
  if (chompKeep && comment2)
34954
36425
  chompKeep = false;
34955
- lines.push(blockItemPrefix + str2);
36426
+ lines.push(blockItemPrefix + str3);
34956
36427
  }
34957
- let str;
36428
+ let str2;
34958
36429
  if (lines.length === 0) {
34959
- str = flowChars.start + flowChars.end;
36430
+ str2 = flowChars.start + flowChars.end;
34960
36431
  } else {
34961
- str = lines[0];
36432
+ str2 = lines[0];
34962
36433
  for (let i = 1;i < lines.length; ++i) {
34963
36434
  const line = lines[i];
34964
- str += line ? `
36435
+ str2 += line ? `
34965
36436
  ${indent}${line}` : `
34966
36437
  `;
34967
36438
  }
34968
36439
  }
34969
36440
  if (comment) {
34970
- str += `
36441
+ str2 += `
34971
36442
  ` + stringifyComment.indentComment(commentString(comment), indent);
34972
36443
  if (onComment)
34973
36444
  onComment();
34974
36445
  } else if (chompKeep && onChompKeep)
34975
36446
  onChompKeep();
34976
- return str;
36447
+ return str2;
34977
36448
  }
34978
36449
  function stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {
34979
36450
  const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
@@ -35016,22 +36487,22 @@ ${indent}${line}` : `
35016
36487
  }
35017
36488
  if (comment)
35018
36489
  reqNewline = true;
35019
- let str = stringify.stringify(item, itemCtx, () => comment = null);
35020
- reqNewline || (reqNewline = lines.length > linesAtValue || str.includes(`
36490
+ let str2 = stringify.stringify(item, itemCtx, () => comment = null);
36491
+ reqNewline || (reqNewline = lines.length > linesAtValue || str2.includes(`
35021
36492
  `));
35022
36493
  if (i < items.length - 1) {
35023
- str += ",";
36494
+ str2 += ",";
35024
36495
  } else if (ctx.options.trailingComma) {
35025
36496
  if (ctx.options.lineWidth > 0) {
35026
- reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str.length + 2) > ctx.options.lineWidth);
36497
+ reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str2.length + 2) > ctx.options.lineWidth);
35027
36498
  }
35028
36499
  if (reqNewline) {
35029
- str += ",";
36500
+ str2 += ",";
35030
36501
  }
35031
36502
  }
35032
36503
  if (comment)
35033
- str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
35034
- lines.push(str);
36504
+ str2 += stringifyComment.lineComment(str2, itemIndent, commentString(comment));
36505
+ lines.push(str2);
35035
36506
  linesAtValue = lines.length;
35036
36507
  }
35037
36508
  const { start, end } = flowChars;
@@ -35043,12 +36514,12 @@ ${indent}${line}` : `
35043
36514
  reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth;
35044
36515
  }
35045
36516
  if (reqNewline) {
35046
- let str = start;
36517
+ let str2 = start;
35047
36518
  for (const line of lines)
35048
- str += line ? `
36519
+ str2 += line ? `
35049
36520
  ${indentStep}${indent}${line}` : `
35050
36521
  `;
35051
- return `${str}
36522
+ return `${str2}
35052
36523
  ${indent}${end}`;
35053
36524
  } else {
35054
36525
  return `${start}${fcPadding}${lines.join(" ")}${fcPadding}${end}`;
@@ -35331,7 +36802,7 @@ var require_string = __commonJS((exports) => {
35331
36802
  identify: (value) => typeof value === "string",
35332
36803
  default: true,
35333
36804
  tag: "tag:yaml.org,2002:str",
35334
- resolve: (str) => str,
36805
+ resolve: (str2) => str2,
35335
36806
  stringify(item, ctx, onComment, onChompKeep) {
35336
36807
  ctx = Object.assign({ actualString: true }, ctx);
35337
36808
  return stringifyString.stringifyString(item, ctx, onComment, onChompKeep);
@@ -35363,7 +36834,7 @@ var require_bool = __commonJS((exports) => {
35363
36834
  default: true,
35364
36835
  tag: "tag:yaml.org,2002:bool",
35365
36836
  test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,
35366
- resolve: (str) => new Scalar.Scalar(str[0] === "t" || str[0] === "T"),
36837
+ resolve: (str2) => new Scalar.Scalar(str2[0] === "t" || str2[0] === "T"),
35367
36838
  stringify({ source, value }, ctx) {
35368
36839
  if (source && boolTag.test.test(source)) {
35369
36840
  const sv = source[0] === "t" || source[0] === "T";
@@ -35409,7 +36880,7 @@ var require_float = __commonJS((exports) => {
35409
36880
  default: true,
35410
36881
  tag: "tag:yaml.org,2002:float",
35411
36882
  test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
35412
- resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
36883
+ resolve: (str2) => str2.slice(-3).toLowerCase() === "nan" ? NaN : str2[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
35413
36884
  stringify: stringifyNumber.stringifyNumber
35414
36885
  };
35415
36886
  var floatExp = {
@@ -35418,7 +36889,7 @@ var require_float = __commonJS((exports) => {
35418
36889
  tag: "tag:yaml.org,2002:float",
35419
36890
  format: "EXP",
35420
36891
  test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/,
35421
- resolve: (str) => parseFloat(str),
36892
+ resolve: (str2) => parseFloat(str2),
35422
36893
  stringify(node) {
35423
36894
  const num3 = Number(node.value);
35424
36895
  return isFinite(num3) ? num3.toExponential() : stringifyNumber.stringifyNumber(node);
@@ -35429,11 +36900,11 @@ var require_float = __commonJS((exports) => {
35429
36900
  default: true,
35430
36901
  tag: "tag:yaml.org,2002:float",
35431
36902
  test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,
35432
- resolve(str) {
35433
- const node = new Scalar.Scalar(parseFloat(str));
35434
- const dot = str.indexOf(".");
35435
- if (dot !== -1 && str[str.length - 1] === "0")
35436
- node.minFractionDigits = str.length - dot - 1;
36903
+ resolve(str2) {
36904
+ const node = new Scalar.Scalar(parseFloat(str2));
36905
+ const dot = str2.indexOf(".");
36906
+ if (dot !== -1 && str2[str2.length - 1] === "0")
36907
+ node.minFractionDigits = str2.length - dot - 1;
35437
36908
  return node;
35438
36909
  },
35439
36910
  stringify: stringifyNumber.stringifyNumber
@@ -35447,7 +36918,7 @@ var require_float = __commonJS((exports) => {
35447
36918
  var require_int = __commonJS((exports) => {
35448
36919
  var stringifyNumber = require_stringifyNumber();
35449
36920
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
35450
- var intResolve = (str, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix);
36921
+ var intResolve = (str2, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str2) : parseInt(str2.substring(offset), radix);
35451
36922
  function intStringify(node, radix, prefix) {
35452
36923
  const { value } = node;
35453
36924
  if (intIdentify(value) && value >= 0)
@@ -35460,15 +36931,15 @@ var require_int = __commonJS((exports) => {
35460
36931
  tag: "tag:yaml.org,2002:int",
35461
36932
  format: "OCT",
35462
36933
  test: /^0o[0-7]+$/,
35463
- resolve: (str, _onError, opt) => intResolve(str, 2, 8, opt),
36934
+ resolve: (str2, _onError, opt) => intResolve(str2, 2, 8, opt),
35464
36935
  stringify: (node) => intStringify(node, 8, "0o")
35465
36936
  };
35466
- var int = {
36937
+ var int2 = {
35467
36938
  identify: intIdentify,
35468
36939
  default: true,
35469
36940
  tag: "tag:yaml.org,2002:int",
35470
36941
  test: /^[-+]?[0-9]+$/,
35471
- resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
36942
+ resolve: (str2, _onError, opt) => intResolve(str2, 0, 10, opt),
35472
36943
  stringify: stringifyNumber.stringifyNumber
35473
36944
  };
35474
36945
  var intHex = {
@@ -35477,10 +36948,10 @@ var require_int = __commonJS((exports) => {
35477
36948
  tag: "tag:yaml.org,2002:int",
35478
36949
  format: "HEX",
35479
36950
  test: /^0x[0-9a-fA-F]+$/,
35480
- resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
36951
+ resolve: (str2, _onError, opt) => intResolve(str2, 2, 16, opt),
35481
36952
  stringify: (node) => intStringify(node, 16, "0x")
35482
36953
  };
35483
- exports.int = int;
36954
+ exports.int = int2;
35484
36955
  exports.intHex = intHex;
35485
36956
  exports.intOct = intOct;
35486
36957
  });
@@ -35491,18 +36962,18 @@ var require_schema = __commonJS((exports) => {
35491
36962
  var _null = require_null();
35492
36963
  var seq2 = require_seq();
35493
36964
  var string = require_string();
35494
- var bool = require_bool();
36965
+ var bool2 = require_bool();
35495
36966
  var float = require_float();
35496
- var int = require_int();
36967
+ var int2 = require_int();
35497
36968
  var schema = [
35498
36969
  map.map,
35499
36970
  seq2.seq,
35500
36971
  string.string,
35501
36972
  _null.nullTag,
35502
- bool.boolTag,
35503
- int.intOct,
35504
- int.int,
35505
- int.intHex,
36973
+ bool2.boolTag,
36974
+ int2.intOct,
36975
+ int2.int,
36976
+ int2.intHex,
35506
36977
  float.floatNaN,
35507
36978
  float.floatExp,
35508
36979
  float.float
@@ -35524,7 +36995,7 @@ var require_schema2 = __commonJS((exports) => {
35524
36995
  identify: (value) => typeof value === "string",
35525
36996
  default: true,
35526
36997
  tag: "tag:yaml.org,2002:str",
35527
- resolve: (str) => str,
36998
+ resolve: (str2) => str2,
35528
36999
  stringify: stringifyJSON
35529
37000
  },
35530
37001
  {
@@ -35541,7 +37012,7 @@ var require_schema2 = __commonJS((exports) => {
35541
37012
  default: true,
35542
37013
  tag: "tag:yaml.org,2002:bool",
35543
37014
  test: /^true$|^false$/,
35544
- resolve: (str) => str === "true",
37015
+ resolve: (str2) => str2 === "true",
35545
37016
  stringify: stringifyJSON
35546
37017
  },
35547
37018
  {
@@ -35549,7 +37020,7 @@ var require_schema2 = __commonJS((exports) => {
35549
37020
  default: true,
35550
37021
  tag: "tag:yaml.org,2002:int",
35551
37022
  test: /^-?(?:0|[1-9][0-9]*)$/,
35552
- resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),
37023
+ resolve: (str2, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str2) : parseInt(str2, 10),
35553
37024
  stringify: ({ value }) => intIdentify(value) ? value.toString() : JSON.stringify(value)
35554
37025
  },
35555
37026
  {
@@ -35557,7 +37028,7 @@ var require_schema2 = __commonJS((exports) => {
35557
37028
  default: true,
35558
37029
  tag: "tag:yaml.org,2002:float",
35559
37030
  test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,
35560
- resolve: (str) => parseFloat(str),
37031
+ resolve: (str2) => parseFloat(str2),
35561
37032
  stringify: stringifyJSON
35562
37033
  }
35563
37034
  ];
@@ -35565,9 +37036,9 @@ var require_schema2 = __commonJS((exports) => {
35565
37036
  default: true,
35566
37037
  tag: "",
35567
37038
  test: /^/,
35568
- resolve(str, onError) {
35569
- onError(`Unresolved plain scalar ${JSON.stringify(str)}`);
35570
- return str;
37039
+ resolve(str2, onError) {
37040
+ onError(`Unresolved plain scalar ${JSON.stringify(str2)}`);
37041
+ return str2;
35571
37042
  }
35572
37043
  };
35573
37044
  var schema = [map.map, seq2.seq].concat(jsonScalars, jsonError);
@@ -35587,10 +37058,10 @@ var require_binary = __commonJS((exports) => {
35587
37058
  if (typeof node_buffer.Buffer === "function") {
35588
37059
  return node_buffer.Buffer.from(src, "base64");
35589
37060
  } else if (typeof atob === "function") {
35590
- const str = atob(src.replace(/[\n\r]/g, ""));
35591
- const buffer = new Uint8Array(str.length);
35592
- for (let i = 0;i < str.length; ++i)
35593
- buffer[i] = str.charCodeAt(i);
37061
+ const str2 = atob(src.replace(/[\n\r]/g, ""));
37062
+ const buffer = new Uint8Array(str2.length);
37063
+ for (let i = 0;i < str2.length; ++i)
37064
+ buffer[i] = str2.charCodeAt(i);
35594
37065
  return buffer;
35595
37066
  } else {
35596
37067
  onError("This environment does not support reading binary tags; either Buffer or atob is required");
@@ -35601,29 +37072,29 @@ var require_binary = __commonJS((exports) => {
35601
37072
  if (!value)
35602
37073
  return "";
35603
37074
  const buf = value;
35604
- let str;
37075
+ let str2;
35605
37076
  if (typeof node_buffer.Buffer === "function") {
35606
- str = buf instanceof node_buffer.Buffer ? buf.toString("base64") : node_buffer.Buffer.from(buf.buffer).toString("base64");
37077
+ str2 = buf instanceof node_buffer.Buffer ? buf.toString("base64") : node_buffer.Buffer.from(buf.buffer).toString("base64");
35607
37078
  } else if (typeof btoa === "function") {
35608
37079
  let s = "";
35609
37080
  for (let i = 0;i < buf.length; ++i)
35610
37081
  s += String.fromCharCode(buf[i]);
35611
- str = btoa(s);
37082
+ str2 = btoa(s);
35612
37083
  } else {
35613
37084
  throw new Error("This environment does not support writing binary tags; either Buffer or btoa is required");
35614
37085
  }
35615
37086
  type2 ?? (type2 = Scalar.Scalar.BLOCK_LITERAL);
35616
37087
  if (type2 !== Scalar.Scalar.QUOTE_DOUBLE) {
35617
37088
  const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);
35618
- const n = Math.ceil(str.length / lineWidth);
37089
+ const n = Math.ceil(str2.length / lineWidth);
35619
37090
  const lines = new Array(n);
35620
37091
  for (let i = 0, o = 0;i < n; ++i, o += lineWidth) {
35621
- lines[i] = str.substr(o, lineWidth);
37092
+ lines[i] = str2.substr(o, lineWidth);
35622
37093
  }
35623
- str = lines.join(type2 === Scalar.Scalar.BLOCK_LITERAL ? `
37094
+ str2 = lines.join(type2 === Scalar.Scalar.BLOCK_LITERAL ? `
35624
37095
  ` : " ");
35625
37096
  }
35626
- return stringifyString.stringifyString({ comment, type: type2, value: str }, ctx, onComment, onChompKeep);
37097
+ return stringifyString.stringifyString({ comment, type: type2, value: str2 }, ctx, onComment, onChompKeep);
35627
37098
  }
35628
37099
  };
35629
37100
  exports.binary = binary;
@@ -35814,7 +37285,7 @@ var require_float2 = __commonJS((exports) => {
35814
37285
  default: true,
35815
37286
  tag: "tag:yaml.org,2002:float",
35816
37287
  test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
35817
- resolve: (str) => str.slice(-3).toLowerCase() === "nan" ? NaN : str[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
37288
+ resolve: (str2) => str2.slice(-3).toLowerCase() === "nan" ? NaN : str2[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY,
35818
37289
  stringify: stringifyNumber.stringifyNumber
35819
37290
  };
35820
37291
  var floatExp = {
@@ -35823,7 +37294,7 @@ var require_float2 = __commonJS((exports) => {
35823
37294
  tag: "tag:yaml.org,2002:float",
35824
37295
  format: "EXP",
35825
37296
  test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/,
35826
- resolve: (str) => parseFloat(str.replace(/_/g, "")),
37297
+ resolve: (str2) => parseFloat(str2.replace(/_/g, "")),
35827
37298
  stringify(node) {
35828
37299
  const num3 = Number(node.value);
35829
37300
  return isFinite(num3) ? num3.toExponential() : stringifyNumber.stringifyNumber(node);
@@ -35834,11 +37305,11 @@ var require_float2 = __commonJS((exports) => {
35834
37305
  default: true,
35835
37306
  tag: "tag:yaml.org,2002:float",
35836
37307
  test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,
35837
- resolve(str) {
35838
- const node = new Scalar.Scalar(parseFloat(str.replace(/_/g, "")));
35839
- const dot = str.indexOf(".");
37308
+ resolve(str2) {
37309
+ const node = new Scalar.Scalar(parseFloat(str2.replace(/_/g, "")));
37310
+ const dot = str2.indexOf(".");
35840
37311
  if (dot !== -1) {
35841
- const f = str.substring(dot + 1).replace(/_/g, "");
37312
+ const f = str2.substring(dot + 1).replace(/_/g, "");
35842
37313
  if (f[f.length - 1] === "0")
35843
37314
  node.minFractionDigits = f.length;
35844
37315
  }
@@ -35855,34 +37326,34 @@ var require_float2 = __commonJS((exports) => {
35855
37326
  var require_int2 = __commonJS((exports) => {
35856
37327
  var stringifyNumber = require_stringifyNumber();
35857
37328
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
35858
- function intResolve(str, offset, radix, { intAsBigInt }) {
35859
- const sign = str[0];
37329
+ function intResolve(str2, offset, radix, { intAsBigInt }) {
37330
+ const sign = str2[0];
35860
37331
  if (sign === "-" || sign === "+")
35861
37332
  offset += 1;
35862
- str = str.substring(offset).replace(/_/g, "");
37333
+ str2 = str2.substring(offset).replace(/_/g, "");
35863
37334
  if (intAsBigInt) {
35864
37335
  switch (radix) {
35865
37336
  case 2:
35866
- str = `0b${str}`;
37337
+ str2 = `0b${str2}`;
35867
37338
  break;
35868
37339
  case 8:
35869
- str = `0o${str}`;
37340
+ str2 = `0o${str2}`;
35870
37341
  break;
35871
37342
  case 16:
35872
- str = `0x${str}`;
37343
+ str2 = `0x${str2}`;
35873
37344
  break;
35874
37345
  }
35875
- const n2 = BigInt(str);
37346
+ const n2 = BigInt(str2);
35876
37347
  return sign === "-" ? BigInt(-1) * n2 : n2;
35877
37348
  }
35878
- const n = parseInt(str, radix);
37349
+ const n = parseInt(str2, radix);
35879
37350
  return sign === "-" ? -1 * n : n;
35880
37351
  }
35881
37352
  function intStringify(node, radix, prefix) {
35882
37353
  const { value } = node;
35883
37354
  if (intIdentify(value)) {
35884
- const str = value.toString(radix);
35885
- return value < 0 ? "-" + prefix + str.substr(1) : prefix + str;
37355
+ const str2 = value.toString(radix);
37356
+ return value < 0 ? "-" + prefix + str2.substr(1) : prefix + str2;
35886
37357
  }
35887
37358
  return stringifyNumber.stringifyNumber(node);
35888
37359
  }
@@ -35892,7 +37363,7 @@ var require_int2 = __commonJS((exports) => {
35892
37363
  tag: "tag:yaml.org,2002:int",
35893
37364
  format: "BIN",
35894
37365
  test: /^[-+]?0b[0-1_]+$/,
35895
- resolve: (str, _onError, opt) => intResolve(str, 2, 2, opt),
37366
+ resolve: (str2, _onError, opt) => intResolve(str2, 2, 2, opt),
35896
37367
  stringify: (node) => intStringify(node, 2, "0b")
35897
37368
  };
35898
37369
  var intOct = {
@@ -35901,15 +37372,15 @@ var require_int2 = __commonJS((exports) => {
35901
37372
  tag: "tag:yaml.org,2002:int",
35902
37373
  format: "OCT",
35903
37374
  test: /^[-+]?0[0-7_]+$/,
35904
- resolve: (str, _onError, opt) => intResolve(str, 1, 8, opt),
37375
+ resolve: (str2, _onError, opt) => intResolve(str2, 1, 8, opt),
35905
37376
  stringify: (node) => intStringify(node, 8, "0")
35906
37377
  };
35907
- var int = {
37378
+ var int2 = {
35908
37379
  identify: intIdentify,
35909
37380
  default: true,
35910
37381
  tag: "tag:yaml.org,2002:int",
35911
37382
  test: /^[-+]?[0-9][0-9_]*$/,
35912
- resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),
37383
+ resolve: (str2, _onError, opt) => intResolve(str2, 0, 10, opt),
35913
37384
  stringify: stringifyNumber.stringifyNumber
35914
37385
  };
35915
37386
  var intHex = {
@@ -35918,10 +37389,10 @@ var require_int2 = __commonJS((exports) => {
35918
37389
  tag: "tag:yaml.org,2002:int",
35919
37390
  format: "HEX",
35920
37391
  test: /^[-+]?0x[0-9a-fA-F_]+$/,
35921
- resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),
37392
+ resolve: (str2, _onError, opt) => intResolve(str2, 2, 16, opt),
35922
37393
  stringify: (node) => intStringify(node, 16, "0x")
35923
37394
  };
35924
- exports.int = int;
37395
+ exports.int = int2;
35925
37396
  exports.intBin = intBin;
35926
37397
  exports.intHex = intHex;
35927
37398
  exports.intOct = intOct;
@@ -36013,9 +37484,9 @@ var require_set = __commonJS((exports) => {
36013
37484
  // node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
36014
37485
  var require_timestamp = __commonJS((exports) => {
36015
37486
  var stringifyNumber = require_stringifyNumber();
36016
- function parseSexagesimal(str, asBigInt) {
36017
- const sign = str[0];
36018
- const parts = sign === "-" || sign === "+" ? str.substring(1) : str;
37487
+ function parseSexagesimal(str2, asBigInt) {
37488
+ const sign = str2[0];
37489
+ const parts = sign === "-" || sign === "+" ? str2.substring(1) : str2;
36019
37490
  const num3 = (n) => asBigInt ? BigInt(n) : Number(n);
36020
37491
  const res = parts.replace(/_/g, "").split(":").reduce((res2, p) => res2 * num3(60) + num3(p), num3(0));
36021
37492
  return sign === "-" ? num3(-1) * res : res;
@@ -36052,7 +37523,7 @@ var require_timestamp = __commonJS((exports) => {
36052
37523
  tag: "tag:yaml.org,2002:int",
36053
37524
  format: "TIME",
36054
37525
  test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,
36055
- resolve: (str, _onError, { intAsBigInt }) => parseSexagesimal(str, intAsBigInt),
37526
+ resolve: (str2, _onError, { intAsBigInt }) => parseSexagesimal(str2, intAsBigInt),
36056
37527
  stringify: stringifySexagesimal
36057
37528
  };
36058
37529
  var floatTime = {
@@ -36061,7 +37532,7 @@ var require_timestamp = __commonJS((exports) => {
36061
37532
  tag: "tag:yaml.org,2002:float",
36062
37533
  format: "TIME",
36063
37534
  test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/,
36064
- resolve: (str) => parseSexagesimal(str, false),
37535
+ resolve: (str2) => parseSexagesimal(str2, false),
36065
37536
  stringify: stringifySexagesimal
36066
37537
  };
36067
37538
  var timestamp = {
@@ -36069,8 +37540,8 @@ var require_timestamp = __commonJS((exports) => {
36069
37540
  default: true,
36070
37541
  tag: "tag:yaml.org,2002:timestamp",
36071
37542
  test: RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})" + "(?:" + "(?:t|T|[ \\t]+)" + "([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)" + "(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?" + ")?$"),
36072
- resolve(str) {
36073
- const match = str.match(timestamp.test);
37543
+ resolve(str2) {
37544
+ const match = str2.match(timestamp.test);
36074
37545
  if (!match)
36075
37546
  throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
36076
37547
  const [, year, month, day, hour, minute, second] = match.map(Number);
@@ -36099,9 +37570,9 @@ var require_schema3 = __commonJS((exports) => {
36099
37570
  var seq2 = require_seq();
36100
37571
  var string = require_string();
36101
37572
  var binary = require_binary();
36102
- var bool = require_bool2();
37573
+ var bool2 = require_bool2();
36103
37574
  var float = require_float2();
36104
- var int = require_int2();
37575
+ var int2 = require_int2();
36105
37576
  var merge = require_merge();
36106
37577
  var omap = require_omap();
36107
37578
  var pairs = require_pairs();
@@ -36112,12 +37583,12 @@ var require_schema3 = __commonJS((exports) => {
36112
37583
  seq2.seq,
36113
37584
  string.string,
36114
37585
  _null.nullTag,
36115
- bool.trueTag,
36116
- bool.falseTag,
36117
- int.intBin,
36118
- int.intOct,
36119
- int.int,
36120
- int.intHex,
37586
+ bool2.trueTag,
37587
+ bool2.falseTag,
37588
+ int2.intBin,
37589
+ int2.intOct,
37590
+ int2.int,
37591
+ int2.intHex,
36121
37592
  float.floatNaN,
36122
37593
  float.floatExp,
36123
37594
  float.float,
@@ -36139,9 +37610,9 @@ var require_tags = __commonJS((exports) => {
36139
37610
  var _null = require_null();
36140
37611
  var seq2 = require_seq();
36141
37612
  var string = require_string();
36142
- var bool = require_bool();
37613
+ var bool2 = require_bool();
36143
37614
  var float = require_float();
36144
- var int = require_int();
37615
+ var int2 = require_int();
36145
37616
  var schema = require_schema();
36146
37617
  var schema$1 = require_schema2();
36147
37618
  var binary = require_binary();
@@ -36160,14 +37631,14 @@ var require_tags = __commonJS((exports) => {
36160
37631
  ]);
36161
37632
  var tagsByName = {
36162
37633
  binary: binary.binary,
36163
- bool: bool.boolTag,
37634
+ bool: bool2.boolTag,
36164
37635
  float: float.float,
36165
37636
  floatExp: float.floatExp,
36166
37637
  floatNaN: float.floatNaN,
36167
37638
  floatTime: timestamp.floatTime,
36168
- int: int.int,
36169
- intHex: int.intHex,
36170
- intOct: int.intOct,
37639
+ int: int2.int,
37640
+ intHex: int2.intHex,
37641
+ intOct: int2.intOct,
36171
37642
  intTime: timestamp.intTime,
36172
37643
  map: map.map,
36173
37644
  merge: merge.merge,
@@ -36533,11 +38004,11 @@ var require_Document = __commonJS((exports) => {
36533
38004
  else
36534
38005
  throw new Error(`With a null YAML version, the { schema: Schema } option is required`);
36535
38006
  }
36536
- toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
38007
+ toJS({ json: json2, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {
36537
38008
  const ctx = {
36538
38009
  anchors: new Map,
36539
38010
  doc: this,
36540
- keep: !json,
38011
+ keep: !json2,
36541
38012
  mapAsMap: mapAsMap === true,
36542
38013
  mapKeyWarned: false,
36543
38014
  maxAliasCount: typeof maxAliasCount === "number" ? maxAliasCount : 100
@@ -39167,15 +40638,15 @@ var require_parser = __commonJS((exports) => {
39167
40638
  var node_process = __require("process");
39168
40639
  var cst = require_cst();
39169
40640
  var lexer = require_lexer();
39170
- function includesToken(list, type2) {
39171
- for (let i = 0;i < list.length; ++i)
39172
- if (list[i].type === type2)
40641
+ function includesToken(list2, type2) {
40642
+ for (let i = 0;i < list2.length; ++i)
40643
+ if (list2[i].type === type2)
39173
40644
  return true;
39174
40645
  return false;
39175
40646
  }
39176
- function findNonEmptyIndex(list) {
39177
- for (let i = 0;i < list.length; ++i) {
39178
- switch (list[i].type) {
40647
+ function findNonEmptyIndex(list2) {
40648
+ for (let i = 0;i < list2.length; ++i) {
40649
+ switch (list2[i].type) {
39179
40650
  case "space":
39180
40651
  case "comment":
39181
40652
  case "newline":
@@ -41302,508 +42773,86 @@ async function certList(projectDir) {
41302
42773
  return;
41303
42774
  }
41304
42775
  for (const e of m.certifications) {
41305
- const mark = isFullyPassed(e) ? pc.green("✔") : pc.red("✘");
41306
- getDefaultChannel().writeLine(` ${mark} ${e.model} ${pc.dim(e.providerUrl)} ${e.mmaVersion} ${e.certifiedAt.slice(0, 10)} ${e.suite.passed}/${e.suite.total} pass`);
41307
- }
41308
- }
41309
- async function uncertify(name, config, projectDir) {
41310
- const removed = removeCertification(name, config.provider.baseUrl, {
41311
- projectDir
41312
- });
41313
- if (removed.global || removed.project)
41314
- getDefaultChannel().writeLine(t("cli.cert_uncertified", { model: name }));
41315
- else
41316
- getDefaultChannel().writeLine(t("cli.cert_not_found", { model: name }));
41317
- }
41318
- function summarize(results) {
41319
- return {
41320
- passed: results.filter((r) => r.status === "pass").length,
41321
- failed: results.filter((r) => r.status === "fail").length,
41322
- skipped: results.filter((r) => r.status === "skipped").length,
41323
- total: results.length
41324
- };
41325
- }
41326
- function mergePartialResults(fresh, previous, rerunIds) {
41327
- const preserved = previous.filter((r) => !rerunIds.has(r.id));
41328
- if (preserved.length > 0) {
41329
- getDefaultChannel().writeLine(pc.dim(t("cli.cert_partial_merge", { kept: String(preserved.length) })));
41330
- }
41331
- return [...fresh, ...preserved];
41332
- }
41333
- function printResults(results) {
41334
- for (const r of results) {
41335
- const icon = r.status === "pass" ? pc.green("✔") : r.status === "fail" ? pc.red("✘") : r.status === "skipped" ? pc.dim("–") : pc.yellow("!");
41336
- const detail = r.status === "skipped" ? pc.dim(r.title) : `${r.passed}/${r.of}`;
41337
- getDefaultChannel().writeLine(` ${icon} ${r.id} ${detail}`);
41338
- if (r.error)
41339
- getDefaultChannel().writeLine(` ${pc.dim(r.error)}`);
41340
- if (r.diagnostics)
41341
- getDefaultChannel().writeLine(r.diagnostics);
41342
- }
41343
- }
41344
- function writeReport(entry, projectDir) {
41345
- const reportDir = join49(projectDir, "certification");
41346
- const ts = entry.certifiedAt.replace(/[:.]/g, "-").slice(0, 19);
41347
- const filename = `report-${entry.model.replace(/[/\\:]/g, "_")}-${ts}.json`;
41348
- const reportPath = join49(reportDir, filename);
41349
- const report = {
41350
- model: entry.model,
41351
- providerUrl: entry.providerUrl,
41352
- mmaVersion: entry.mmaVersion,
41353
- certifiedAt: entry.certifiedAt,
41354
- certified: isFullyPassed(entry),
41355
- suite: entry.suite,
41356
- results: entry.results.map((r) => ({
41357
- id: r.id,
41358
- title: r.title,
41359
- status: r.status,
41360
- passed: r.passed,
41361
- of: r.of,
41362
- error: r.error,
41363
- diagnostics: r.diagnostics
41364
- }))
41365
- };
41366
- try {
41367
- writeFileSync23(reportPath, JSON.stringify(report, null, 2), "utf-8");
41368
- getDefaultChannel().writeLine(pc.dim(`
41369
- Report: ${reportPath}`));
41370
- } catch (e) {
41371
- getDefaultChannel().writeLine(pc.yellow(` Failed to write report: ${e.message}`), "stderr");
41372
- }
41373
- }
41374
- var HERE, MMA_ROOT;
41375
- var init_cli = __esm(() => {
41376
- init_paths();
41377
- init_i18n();
41378
- init_colors();
41379
- init_loader3();
41380
- init_runner2();
41381
- init_manifest();
41382
- init_output();
41383
- HERE = dirname24(fileURLToPath5(import.meta.url));
41384
- MMA_ROOT = findMmaRoot(HERE);
41385
- });
41386
-
41387
- // src/config/registry.ts
41388
- function shareField(key, canonical) {
41389
- const field = key === "system" ? "systemPrompt" : "responseReserve";
41390
- const other = key === "system" ? "responseReserve" : "systemPrompt";
41391
- return {
41392
- key: canonical,
41393
- aliases: [`context.${key}`],
41394
- domain: "budget",
41395
- valueType: "share",
41396
- min: MIN_SHARE2,
41397
- max: MAX_SHARE2,
41398
- step: 0.01,
41399
- reconfigure: true,
41400
- get: (c) => c.contextBudget[field],
41401
- set: (c, v) => setBudgetShare(c, key, v),
41402
- extraValidate: (c, v) => {
41403
- const n = v;
41404
- const total = n + c.contextBudget[other];
41405
- return total > MAX_COMBINED2 ? "combined" : null;
41406
- }
41407
- };
41408
- }
41409
- function securityToggle(field, canonical) {
41410
- return {
41411
- key: canonical,
41412
- aliases: [],
41413
- domain: "security",
41414
- valueType: "bool",
41415
- reconfigure: false,
41416
- get: (c) => {
41417
- const sec = c.security;
41418
- if (!sec)
41419
- return false;
41420
- return field === "enabled" ? sec.enabled : sec[field].enabled;
41421
- },
41422
- set: (c, v) => {
41423
- if (!c.security)
41424
- c.security = structuredClone(DEFAULT_SECURITY_CONFIG);
41425
- if (field === "enabled")
41426
- c.security.enabled = v;
41427
- else
41428
- c.security[field].enabled = v;
41429
- }
41430
- };
41431
- }
41432
- function resolveConfigKey(name) {
41433
- return BY_NAME.get(name) ?? null;
41434
- }
41435
- function configDefs() {
41436
- return DEFINITIONS;
41437
- }
41438
- function canonicalKeys() {
41439
- return DEFINITIONS.map((d) => d.key);
41440
- }
41441
- function keysForGroup(prefix) {
41442
- return DEFINITIONS.filter((d) => d.key.startsWith(`${prefix}.`));
41443
- }
41444
- function allConfigNames() {
41445
- const out = [];
41446
- for (const def of DEFINITIONS) {
41447
- out.push({ name: def.key, def, alias: false });
41448
- for (const a of def.aliases)
41449
- out.push({ name: a, def, alias: true });
41450
- }
41451
- return out;
41452
- }
41453
- function formatConfigValue(value) {
41454
- if (typeof value === "boolean")
41455
- return value ? "on" : "off";
41456
- return String(value);
41457
- }
41458
- function parseBool(raw) {
41459
- const v = raw.trim().toLowerCase();
41460
- if (["on", "true", "1", "yes", "y", "enable", "enabled"].includes(v))
41461
- return { ok: true, value: true };
41462
- if (["off", "false", "0", "no", "n", "disable", "disabled"].includes(v))
41463
- return { ok: true, value: false };
41464
- return { ok: false, reason: "invalid" };
41465
- }
41466
- function parseConfigValue(def, raw) {
41467
- const trimmed = raw.trim();
41468
- switch (def.valueType) {
41469
- case "string":
41470
- return trimmed.length > 0 ? { ok: true, value: trimmed } : { ok: false, reason: "invalid" };
41471
- case "bool":
41472
- return parseBool(trimmed);
41473
- case "enum": {
41474
- const v = trimmed.toLowerCase();
41475
- if (def.enumValues && !def.enumValues.includes(v))
41476
- return { ok: false, reason: "invalid" };
41477
- return { ok: true, value: v };
41478
- }
41479
- case "int": {
41480
- if (!/^-?\d+$/.test(trimmed))
41481
- return { ok: false, reason: "invalid" };
41482
- const n = Number(trimmed);
41483
- if (!Number.isFinite(n))
41484
- return { ok: false, reason: "invalid" };
41485
- if (def.min !== undefined && n < def.min)
41486
- return { ok: false, reason: "invalid" };
41487
- if (def.max !== undefined && n > def.max)
41488
- return { ok: false, reason: "invalid" };
41489
- return { ok: true, value: n };
41490
- }
41491
- case "share": {
41492
- const isPct = trimmed.endsWith("%");
41493
- const body = isPct ? trimmed.slice(0, -1).trim() : trimmed;
41494
- if (!/^-?\d+(\.\d+)?$/.test(body))
41495
- return { ok: false, reason: "invalid" };
41496
- let n = Number(body);
41497
- if (isPct)
41498
- n = n / 100;
41499
- if (!Number.isFinite(n) || n < MIN_SHARE2 || n > MAX_SHARE2)
41500
- return { ok: false, reason: "invalid" };
41501
- return { ok: true, value: n };
41502
- }
41503
- }
41504
- }
41505
- function getConfigValue(config, name) {
41506
- const def = resolveConfigKey(name);
41507
- if (!def)
41508
- return { ok: false, reason: "unknown-key", input: name };
41509
- const value = def.get(config);
41510
- return { ok: true, key: def.key, def, value, display: formatConfigValue(value) };
41511
- }
41512
- function applyProviderModelMemory(config, key, value) {
41513
- const provider = config.provider;
41514
- const activeName = provider.active ?? provider.type;
41515
- if (key === "model") {
41516
- if (!activeName)
41517
- return;
41518
- provider.models = { ...provider.models ?? {}, [activeName]: String(value) };
41519
- return;
41520
- }
41521
- if (key === "provider.active") {
41522
- const remembered = provider.models?.[String(value)];
41523
- if (remembered)
41524
- config.model = remembered;
41525
- }
41526
- }
41527
- function setConfigValue(config, name, raw) {
41528
- const def = resolveConfigKey(name);
41529
- if (!def)
41530
- return { ok: false, reason: "unknown-key", input: name };
41531
- if (def.readOnly)
41532
- return { ok: false, reason: "read-only", input: name, key: def.key, def };
41533
- const parsed = parseConfigValue(def, raw);
41534
- if (!parsed.ok)
41535
- return { ok: false, reason: "invalid-value", input: name, key: def.key, def };
41536
- const extra = def.extraValidate?.(config, parsed.value);
41537
- if (extra)
41538
- return { ok: false, reason: extra, input: name, key: def.key, def };
41539
- def.set(config, parsed.value);
41540
- applyProviderModelMemory(config, def.key, parsed.value);
42776
+ const mark = isFullyPassed(e) ? pc.green("✔") : pc.red("✘");
42777
+ getDefaultChannel().writeLine(` ${mark} ${e.model} ${pc.dim(e.providerUrl)} ${e.mmaVersion} ${e.certifiedAt.slice(0, 10)} ${e.suite.passed}/${e.suite.total} pass`);
42778
+ }
42779
+ }
42780
+ async function uncertify(name, config, projectDir) {
42781
+ const removed = removeCertification(name, config.provider.baseUrl, {
42782
+ projectDir
42783
+ });
42784
+ if (removed.global || removed.project)
42785
+ getDefaultChannel().writeLine(t("cli.cert_uncertified", { model: name }));
42786
+ else
42787
+ getDefaultChannel().writeLine(t("cli.cert_not_found", { model: name }));
42788
+ }
42789
+ function summarize(results) {
41541
42790
  return {
41542
- ok: true,
41543
- key: def.key,
41544
- def,
41545
- value: parsed.value,
41546
- display: formatConfigValue(parsed.value),
41547
- reconfigure: def.reconfigure,
41548
- reasoningChanged: def.key === "reasoning.mode"
42791
+ passed: results.filter((r) => r.status === "pass").length,
42792
+ failed: results.filter((r) => r.status === "fail").length,
42793
+ skipped: results.filter((r) => r.status === "skipped").length,
42794
+ total: results.length
41549
42795
  };
41550
42796
  }
41551
- function captureConfigSnapshot(config) {
41552
- const snapshot = new Map;
41553
- for (const def of DEFINITIONS) {
41554
- try {
41555
- snapshot.set(def.key, structuredClone(def.get(config)));
41556
- } catch {}
42797
+ function mergePartialResults(fresh, previous, rerunIds) {
42798
+ const preserved = previous.filter((r) => !rerunIds.has(r.id));
42799
+ if (preserved.length > 0) {
42800
+ getDefaultChannel().writeLine(pc.dim(t("cli.cert_partial_merge", { kept: String(preserved.length) })));
41557
42801
  }
41558
- return snapshot;
42802
+ return [...fresh, ...preserved];
41559
42803
  }
41560
- var REASONING_LEVELS, LOG_LEVELS, VERBOSITY_LEVELS, LOCALES, MIN_SHARE2 = 0.05, MAX_SHARE2 = 0.9, MAX_COMBINED2 = 0.95, DEFINITIONS, BY_NAME;
41561
- var init_registry2 = __esm(() => {
41562
- init_defaults();
41563
- init_security();
41564
- init_budget();
41565
- REASONING_LEVELS = [
41566
- "auto",
41567
- "default",
41568
- "none",
41569
- "low",
41570
- "medium",
41571
- "high",
41572
- "max"
41573
- ];
41574
- LOG_LEVELS = ["silent", "error", "warn", "info", "debug"];
41575
- VERBOSITY_LEVELS = ["quiet", "normal", "verbose"];
41576
- LOCALES = ["en", "ru"];
41577
- DEFINITIONS = [
41578
- {
41579
- key: "model",
41580
- aliases: [],
41581
- domain: "agent",
41582
- valueType: "string",
41583
- reconfigure: true,
41584
- get: (c) => c.model,
41585
- set: (c, v) => {
41586
- c.model = String(v);
41587
- }
41588
- },
41589
- {
41590
- key: "provider.active",
41591
- aliases: [],
41592
- domain: "provider",
41593
- valueType: "string",
41594
- reconfigure: true,
41595
- get: (c) => c.provider.active ?? c.provider.type,
41596
- set: (c, v) => {
41597
- c.provider.active = String(v);
41598
- },
41599
- extraValidate: (c, v) => {
41600
- const entries = c.provider.entries ?? [];
41601
- if (entries.length === 0)
41602
- return null;
41603
- const name = String(v);
41604
- const found = entries.some((e) => e.label === name || e.type === name);
41605
- return found ? null : "invalid";
41606
- }
41607
- },
41608
- {
41609
- key: "contextWindow",
41610
- aliases: ["context.window"],
41611
- domain: "budget",
41612
- valueType: "int",
41613
- min: 1024,
41614
- step: 1024,
41615
- reconfigure: true,
41616
- get: (c) => c.contextWindow,
41617
- set: (c, v) => {
41618
- c.contextWindow = v;
41619
- }
41620
- },
41621
- shareField("system", "contextBudget.systemPrompt"),
41622
- shareField("reserve", "contextBudget.responseReserve"),
41623
- {
41624
- key: "showReasoning",
41625
- aliases: ["reasoning.show"],
41626
- domain: "reasoning",
41627
- valueType: "bool",
41628
- reconfigure: false,
41629
- get: (c) => c.showReasoning,
41630
- set: (c, v) => {
41631
- c.showReasoning = v;
41632
- }
41633
- },
41634
- {
41635
- key: "reasoning.mode",
41636
- aliases: ["reasoning.level"],
41637
- domain: "reasoning",
41638
- valueType: "enum",
41639
- enumValues: REASONING_LEVELS,
41640
- reconfigure: true,
41641
- get: (c) => c.reasoning?.mode ?? "auto",
41642
- set: (c, v) => {
41643
- const base = c.reasoning ?? structuredClone(DEFAULTS.reasoning);
41644
- c.reasoning = { ...base, mode: v };
41645
- }
41646
- },
41647
- {
41648
- key: "ui.verbosity",
41649
- aliases: ["verbosity"],
41650
- domain: "ui",
41651
- valueType: "enum",
41652
- enumValues: VERBOSITY_LEVELS,
41653
- reconfigure: false,
41654
- get: (c) => c.ui.verbosity ?? (c.ui.verbose ? "verbose" : "quiet"),
41655
- set: (c, v) => {
41656
- c.ui.verbosity = v;
41657
- }
41658
- },
41659
- {
41660
- key: "maxToolIterations",
41661
- aliases: [],
41662
- domain: "agent",
41663
- valueType: "int",
41664
- min: 1,
41665
- step: 1,
41666
- reconfigure: false,
41667
- get: (c) => c.maxToolIterations,
41668
- set: (c, v) => {
41669
- c.maxToolIterations = v;
41670
- }
41671
- },
41672
- {
41673
- key: "stuckThreshold",
41674
- aliases: [],
41675
- domain: "agent",
41676
- valueType: "int",
41677
- min: 1,
41678
- step: 1,
41679
- reconfigure: false,
41680
- get: (c) => c.stuckThreshold,
41681
- set: (c, v) => {
41682
- c.stuckThreshold = v;
41683
- }
41684
- },
41685
- {
41686
- key: "moe.enabled",
41687
- aliases: [],
41688
- domain: "agent",
41689
- valueType: "bool",
41690
- reconfigure: true,
41691
- get: (c) => c.moe?.enabled ?? DEFAULTS.moe.enabled,
41692
- set: (c, v) => {
41693
- c.moe = { ...c.moe ?? DEFAULTS.moe, enabled: v };
41694
- }
41695
- },
41696
- {
41697
- key: "moe.maxReplanCycles",
41698
- aliases: [],
41699
- domain: "agent",
41700
- valueType: "int",
41701
- min: 0,
41702
- max: 10,
41703
- step: 1,
41704
- reconfigure: true,
41705
- get: (c) => c.moe?.maxReplanCycles ?? DEFAULTS.moe.maxReplanCycles,
41706
- set: (c, v) => {
41707
- c.moe = { ...c.moe ?? DEFAULTS.moe, maxReplanCycles: v };
41708
- }
41709
- },
41710
- {
41711
- key: "critic.enabled",
41712
- aliases: [],
41713
- domain: "agent",
41714
- valueType: "bool",
41715
- reconfigure: true,
41716
- get: (c) => c.critic?.enabled ?? DEFAULTS.critic.enabled,
41717
- set: (c, v) => {
41718
- c.critic = { ...c.critic ?? DEFAULTS.critic, enabled: v };
41719
- }
41720
- },
41721
- {
41722
- key: "critic.maxCalls",
41723
- aliases: [],
41724
- domain: "agent",
41725
- valueType: "int",
41726
- min: 0,
41727
- max: 20,
41728
- step: 1,
41729
- reconfigure: true,
41730
- get: (c) => c.critic?.maxCalls ?? DEFAULTS.critic.maxCalls,
41731
- set: (c, v) => {
41732
- c.critic = { ...c.critic ?? DEFAULTS.critic, maxCalls: v };
41733
- }
41734
- },
41735
- {
41736
- key: "critic.maxRepairCycles",
41737
- aliases: [],
41738
- domain: "agent",
41739
- valueType: "int",
41740
- min: 0,
41741
- max: 5,
41742
- step: 1,
41743
- reconfigure: true,
41744
- get: (c) => c.critic?.maxRepairCycles ?? DEFAULTS.critic.maxRepairCycles,
41745
- set: (c, v) => {
41746
- c.critic = { ...c.critic ?? DEFAULTS.critic, maxRepairCycles: v };
41747
- }
41748
- },
41749
- {
41750
- key: "critic.timeoutMs",
41751
- aliases: [],
41752
- domain: "agent",
41753
- valueType: "int",
41754
- min: 1000,
41755
- max: 120000,
41756
- step: 1000,
41757
- reconfigure: true,
41758
- get: (c) => c.critic?.timeoutMs ?? DEFAULTS.critic.timeoutMs,
41759
- set: (c, v) => {
41760
- c.critic = { ...c.critic ?? DEFAULTS.critic, timeoutMs: v };
41761
- }
41762
- },
41763
- {
41764
- key: "logLevel",
41765
- aliases: [],
41766
- domain: "agent",
41767
- valueType: "enum",
41768
- enumValues: LOG_LEVELS,
41769
- reconfigure: false,
41770
- get: (c) => c.logLevel,
41771
- set: (c, v) => {
41772
- c.logLevel = String(v);
41773
- }
41774
- },
41775
- {
41776
- key: "locale",
41777
- aliases: [],
41778
- domain: "i18n",
41779
- valueType: "enum",
41780
- enumValues: LOCALES,
41781
- reconfigure: false,
41782
- get: (c) => c.locale,
41783
- set: (c, v) => {
41784
- c.locale = String(v);
41785
- }
41786
- },
41787
- {
41788
- key: "version",
41789
- aliases: [],
41790
- domain: "agent",
41791
- valueType: "string",
41792
- reconfigure: false,
41793
- readOnly: true,
41794
- get: (c) => c.version
41795
- },
41796
- securityToggle("enabled", "security.enabled"),
41797
- securityToggle("paths", "security.paths.enabled"),
41798
- securityToggle("contentScan", "security.contentScan.enabled"),
41799
- securityToggle("sessionEncryption", "security.sessionEncryption.enabled")
41800
- ];
41801
- BY_NAME = new Map;
41802
- for (const def of DEFINITIONS) {
41803
- BY_NAME.set(def.key, def);
41804
- for (const alias of def.aliases)
41805
- BY_NAME.set(alias, def);
42804
+ function printResults(results) {
42805
+ for (const r of results) {
42806
+ const icon = r.status === "pass" ? pc.green("✔") : r.status === "fail" ? pc.red("✘") : r.status === "skipped" ? pc.dim("–") : pc.yellow("!");
42807
+ const detail = r.status === "skipped" ? pc.dim(r.title) : `${r.passed}/${r.of}`;
42808
+ getDefaultChannel().writeLine(` ${icon} ${r.id} ${detail}`);
42809
+ if (r.error)
42810
+ getDefaultChannel().writeLine(` ${pc.dim(r.error)}`);
42811
+ if (r.diagnostics)
42812
+ getDefaultChannel().writeLine(r.diagnostics);
42813
+ }
42814
+ }
42815
+ function writeReport(entry, projectDir) {
42816
+ const reportDir = join49(projectDir, "certification");
42817
+ const ts = entry.certifiedAt.replace(/[:.]/g, "-").slice(0, 19);
42818
+ const filename = `report-${entry.model.replace(/[/\\:]/g, "_")}-${ts}.json`;
42819
+ const reportPath = join49(reportDir, filename);
42820
+ const report = {
42821
+ model: entry.model,
42822
+ providerUrl: entry.providerUrl,
42823
+ mmaVersion: entry.mmaVersion,
42824
+ certifiedAt: entry.certifiedAt,
42825
+ certified: isFullyPassed(entry),
42826
+ suite: entry.suite,
42827
+ results: entry.results.map((r) => ({
42828
+ id: r.id,
42829
+ title: r.title,
42830
+ status: r.status,
42831
+ passed: r.passed,
42832
+ of: r.of,
42833
+ error: r.error,
42834
+ diagnostics: r.diagnostics
42835
+ }))
42836
+ };
42837
+ try {
42838
+ writeFileSync23(reportPath, JSON.stringify(report, null, 2), "utf-8");
42839
+ getDefaultChannel().writeLine(pc.dim(`
42840
+ Report: ${reportPath}`));
42841
+ } catch (e) {
42842
+ getDefaultChannel().writeLine(pc.yellow(` Failed to write report: ${e.message}`), "stderr");
41806
42843
  }
42844
+ }
42845
+ var HERE, MMA_ROOT;
42846
+ var init_cli = __esm(() => {
42847
+ init_paths();
42848
+ init_i18n();
42849
+ init_colors();
42850
+ init_loader3();
42851
+ init_runner2();
42852
+ init_manifest();
42853
+ init_output();
42854
+ HERE = dirname24(fileURLToPath5(import.meta.url));
42855
+ MMA_ROOT = findMmaRoot(HERE);
41807
42856
  });
41808
42857
 
41809
42858
  // src/ui/theme.ts
@@ -42574,8 +43623,8 @@ function rawFromValue(value) {
42574
43623
  return String(value);
42575
43624
  }
42576
43625
  function printConfigTable(ctx, defs) {
42577
- const list = defs ?? configDefs();
42578
- const rows = list.map((def) => [
43626
+ const list2 = defs ?? configDefs();
43627
+ const rows = list2.map((def) => [
42579
43628
  def.key,
42580
43629
  formatConfigValue(def.get(ctx.config)),
42581
43630
  def.domain,
@@ -42873,7 +43922,7 @@ function registerConfigCommands(ctx) {
42873
43922
  });
42874
43923
  }
42875
43924
  function registerProviderCommands(ctx) {
42876
- const list = () => {
43925
+ const list2 = () => {
42877
43926
  const providers = ctx.agent.listProviders();
42878
43927
  if (providers.length === 0) {
42879
43928
  ctx.output.writeLine(`${t("repl.provider_current")} ${ctx.config.provider.type}`);
@@ -42969,7 +44018,7 @@ function registerProviderCommands(ctx) {
42969
44018
  ctx.output.writeLine(t("repl.provider_switch_hint", { name }));
42970
44019
  };
42971
44020
  const handlers = {
42972
- list,
44021
+ list: list2,
42973
44022
  use,
42974
44023
  add
42975
44024
  };
@@ -43105,6 +44154,30 @@ function registerProviderCommands(ctx) {
43105
44154
  });
43106
44155
  }
43107
44156
  function registerAgentCommands(ctx) {
44157
+ const securityStatus = () => {
44158
+ const s = ctx.config.security;
44159
+ const flag = (v) => v ? t("reasoning.on") : t("reasoning.off");
44160
+ const sep3 = pc.dim(" · ");
44161
+ ctx.output.writeLine(`security${sep3}${flag(s?.enabled)}`);
44162
+ ctx.output.writeLine(`↳ bash ${flag(s?.bash.enabled)}${sep3}paths ${flag(s?.paths.enabled)}${sep3}network ${flag(s?.network.enabled)}`);
44163
+ ctx.output.writeLine(`↳ contentScan ${flag(s?.contentScan.enabled)}${sep3}encryption ${flag(s?.sessionEncryption.enabled)}`);
44164
+ };
44165
+ const securityHandlers = {
44166
+ status: securityStatus
44167
+ };
44168
+ ctx.registerCommand({
44169
+ name: "security",
44170
+ description: t("repl.security"),
44171
+ action: (args) => {
44172
+ const sub = args[0]?.trim().toLowerCase();
44173
+ const handler = sub ? securityHandlers[sub] : securityHandlers.status;
44174
+ if (!handler) {
44175
+ ctx.output.writeLine(pc.yellow(t("repl.unknown_sub", { cmd: "security", sub })));
44176
+ return;
44177
+ }
44178
+ handler();
44179
+ }
44180
+ });
43108
44181
  ctx.registerCommand({
43109
44182
  name: "reload",
43110
44183
  description: t("repl.reload"),
@@ -43457,6 +44530,7 @@ var init_repl_commands = __esm(() => {
43457
44530
  sysprompt: "agent",
43458
44531
  map: "agent",
43459
44532
  lsp: "agent",
44533
+ security: "agent",
43460
44534
  sessions: "session",
43461
44535
  new: "session",
43462
44536
  resume: "session",
@@ -44330,6 +45404,7 @@ function extractLatestChangelog(changelog) {
44330
45404
 
44331
45405
  // src/cli/commands.ts
44332
45406
  init_output();
45407
+ init_registry2();
44333
45408
 
44334
45409
  // src/config/redact.ts
44335
45410
  var SECRET_KEYS = new Set([
@@ -44408,29 +45483,39 @@ function buildAgentsCommand(program2) {
44408
45483
  }
44409
45484
  function buildConfigCommands(program2) {
44410
45485
  const configCmd = program2.command("config").description(t("cli.manage_config"));
44411
- configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
45486
+ configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).option("--force", t("cli.config_force")).action(async (key, value, opts) => {
44412
45487
  const configPath = globalConfigFile();
44413
45488
  const { config } = await bootstrap();
44414
- const keys = key.split(".");
44415
- let obj = config;
44416
- for (let i = 0;i < keys.length - 1; i++) {
44417
- if (!(keys[i] in obj))
44418
- obj[keys[i]] = {};
44419
- obj = obj[keys[i]];
44420
- }
44421
- const lastKey = keys[keys.length - 1];
44422
- if (value === "true")
44423
- obj[lastKey] = true;
44424
- else if (value === "false")
44425
- obj[lastKey] = false;
44426
- else if (/^\d+$/.test(value))
44427
- obj[lastKey] = parseInt(value, 10);
44428
- else if (/^\d+\.\d+$/.test(value))
44429
- obj[lastKey] = parseFloat(value);
44430
- else
44431
- obj[lastKey] = value;
45489
+ if (opts.force) {
45490
+ const keys = key.split(".");
45491
+ let obj = config;
45492
+ for (let i = 0;i < keys.length - 1; i++) {
45493
+ if (!(keys[i] in obj))
45494
+ obj[keys[i]] = {};
45495
+ obj = obj[keys[i]];
45496
+ }
45497
+ const lastKey = keys[keys.length - 1];
45498
+ if (value === "true")
45499
+ obj[lastKey] = true;
45500
+ else if (value === "false")
45501
+ obj[lastKey] = false;
45502
+ else if (/^\d+$/.test(value))
45503
+ obj[lastKey] = parseInt(value, 10);
45504
+ else if (/^\d+\.\d+$/.test(value))
45505
+ obj[lastKey] = parseFloat(value);
45506
+ else
45507
+ obj[lastKey] = value;
45508
+ saveConfig(config, configPath, dirname25(configPath));
45509
+ getDefaultChannel().writeLine(t("cli.set_done", { key, value }));
45510
+ return;
45511
+ }
45512
+ const r = setConfigValue(config, key, value);
45513
+ if (!r.ok) {
45514
+ getDefaultChannel().writeLine(pc.yellow(t("cli.config_invalid", { key: r.input, reason: r.reason })), "stderr");
45515
+ return;
45516
+ }
44432
45517
  saveConfig(config, configPath, dirname25(configPath));
44433
- getDefaultChannel().writeLine(t("cli.set_done", { key, value }));
45518
+ getDefaultChannel().writeLine(t("cli.set_done", { key: r.key, value: r.display }));
44434
45519
  });
44435
45520
  configCmd.command("show").description(t("cli.show_config")).option("--show-secrets", "Print secrets (API keys, tokens) unredacted").action(async (opts) => {
44436
45521
  const { config } = await bootstrap();
@@ -45077,7 +46162,7 @@ class LineEditor {
45077
46162
  this.dsrDataHandler = (buf) => this.consumeDsrReplies(buf.toString("utf-8"));
45078
46163
  this.input.on("data", this.dsrDataHandler);
45079
46164
  readline2.emitKeypressEvents(this.input);
45080
- this.keypressHandler = (str, key) => this.onKey(str, key);
46165
+ this.keypressHandler = (str2, key) => this.onKey(str2, key);
45081
46166
  this.input.on("keypress", this.keypressHandler);
45082
46167
  this.input.resume();
45083
46168
  } else {
@@ -45233,7 +46318,7 @@ class LineEditor {
45233
46318
  this.pendingLine = parts[i];
45234
46319
  }
45235
46320
  }
45236
- onKey(str, key) {
46321
+ onKey(str2, key) {
45237
46322
  if (this.isDone)
45238
46323
  return;
45239
46324
  if (!this.inputEnabled) {
@@ -45243,7 +46328,7 @@ class LineEditor {
45243
46328
  return;
45244
46329
  }
45245
46330
  if (k2?.name === "escape") {
45246
- this.onKeyInput?.(str, key);
46331
+ this.onKeyInput?.(str2, key);
45247
46332
  return;
45248
46333
  }
45249
46334
  return;
@@ -45269,11 +46354,11 @@ class LineEditor {
45269
46354
  }
45270
46355
  this.completionSession = null;
45271
46356
  }
45272
- if (this.onKeyInput?.(str, key))
46357
+ if (this.onKeyInput?.(str2, key))
45273
46358
  return;
45274
46359
  const k = key;
45275
46360
  const name = k?.name ?? "undefined";
45276
- const seq2 = k?.sequence ?? str ?? "";
46361
+ const seq2 = k?.sequence ?? str2 ?? "";
45277
46362
  if (name === "undefined" && /^\x1b\[\d+(?:;\d+)?u$/.test(seq2)) {
45278
46363
  const m = seq2.match(/^\x1b\[(\d+)(?:;(\d+))?u$/);
45279
46364
  if (m && Number(m[1]) === 13 && Number(m[2] ?? 0) !== 0) {
@@ -45313,9 +46398,9 @@ class LineEditor {
45313
46398
  this.pasteBuffer += `
45314
46399
  `;
45315
46400
  }
45316
- } else if (str) {
46401
+ } else if (str2) {
45317
46402
  this.pasteLastWasCR = false;
45318
- this.pasteBuffer += str;
46403
+ this.pasteBuffer += str2;
45319
46404
  }
45320
46405
  return;
45321
46406
  }
@@ -45441,9 +46526,9 @@ class LineEditor {
45441
46526
  return;
45442
46527
  }
45443
46528
  }
45444
- if (str && !/^[\u0000-\u001f\u007f]/.test(str)) {
46529
+ if (str2 && !/^[\u0000-\u001f\u007f]/.test(str2)) {
45445
46530
  this.lastWasCR = false;
45446
- this.insertText(str);
46531
+ this.insertText(str2);
45447
46532
  }
45448
46533
  }
45449
46534
  submit() {
@@ -46596,7 +47681,7 @@ var GENERIC_ARG_KEYS = [
46596
47681
  "value",
46597
47682
  "text"
46598
47683
  ];
46599
- function str(value) {
47684
+ function str2(value) {
46600
47685
  if (typeof value === "string")
46601
47686
  return value;
46602
47687
  if (typeof value === "number")
@@ -46637,22 +47722,22 @@ function humanArgs(tool, args) {
46637
47722
  return truncateArg([args.action, ...extras].join(" "));
46638
47723
  }
46639
47724
  if (tool === "move_file") {
46640
- const from = str(args.from);
46641
- const to = str(args.to);
47725
+ const from = str2(args.from);
47726
+ const to = str2(args.to);
46642
47727
  if (from && to)
46643
47728
  return truncateArg(`${from} → ${to}`);
46644
47729
  }
46645
47730
  if (tool === "mcp_call") {
46646
- const server = str(args.server);
46647
- const name = str(args.tool);
47731
+ const server = str2(args.server);
47732
+ const name = str2(args.tool);
46648
47733
  if (server && name)
46649
47734
  return `${server}/${name}`;
46650
47735
  }
46651
47736
  if (tool === "remember") {
46652
- const category = str(args.category);
46653
- const key = str(args.key);
46654
- const entry = str(args.entry);
46655
- const body = key && args.value !== undefined ? `${key} = ${str(args.value)}` : key || entry;
47737
+ const category = str2(args.category);
47738
+ const key = str2(args.key);
47739
+ const entry = str2(args.entry);
47740
+ const body = key && args.value !== undefined ? `${key} = ${str2(args.value)}` : key || entry;
46656
47741
  const phrase = [category, body].filter(Boolean).join(" · ");
46657
47742
  if (phrase)
46658
47743
  return truncateArg(phrase);
@@ -46663,7 +47748,7 @@ function humanArgs(tool, args) {
46663
47748
  return tags.join(", ");
46664
47749
  }
46665
47750
  for (const key of GENERIC_ARG_KEYS) {
46666
- const value = str(args[key]);
47751
+ const value = str2(args[key]);
46667
47752
  if (value)
46668
47753
  return truncateArg(value);
46669
47754
  }
@@ -47558,6 +48643,9 @@ class Repl {
47558
48643
  { name: "normal", description: t("verbose.sub_normal") },
47559
48644
  { name: "verbose", description: t("verbose.sub_verbose") }
47560
48645
  ]));
48646
+ this.completer.registerProvider(new SubcommandProvider("security", [
48647
+ { name: "status", description: t("cli.security.status") }
48648
+ ]));
47561
48649
  this.completer.registerProvider(new ConfigKeyProvider);
47562
48650
  this.completer.registerProvider(new ConfigValueProvider);
47563
48651
  this.completer.registerProvider(new FlagProvider);
@@ -47673,7 +48761,7 @@ ${line}`;
47673
48761
  });
47674
48762
  }
47675
48763
  if (this.rl instanceof LineEditor) {
47676
- this.rl.onKeyInput = (str2, key) => this.handleSpecialKey(str2, key);
48764
+ this.rl.onKeyInput = (str3, key) => this.handleSpecialKey(str3, key);
47677
48765
  }
47678
48766
  let forceExitTimer = null;
47679
48767
  const FORCE_EXIT_MS = 5000;
@@ -48461,6 +49549,7 @@ function overview(store) {
48461
49549
 
48462
49550
  // src/modules/webui/commands-settings.ts
48463
49551
  init_registry2();
49552
+ init_i18n();
48464
49553
  init_export();
48465
49554
  import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync27 } from "node:fs";
48466
49555
  import { dirname as dirname29, join as join56 } from "node:path";
@@ -48522,11 +49611,13 @@ async function applyConfigWrite(cfg, name, value, out, state) {
48522
49611
  init_paths();
48523
49612
  var REASONING_USAGE = "/reasoning [show|hide|on|off|level <auto|default|none|low|medium|high|max>]";
48524
49613
  var CONTEXT_USAGE = "/context [<tokens> | system <share> | reserve <share>]";
49614
+ var SECURITY_USAGE = "/security [status|<key> [value]]";
48525
49615
  function makeSettingsHandlers(state) {
48526
49616
  return {
48527
49617
  reasoning: (args, o) => withConfig(state, o, (cfg) => reasoningCmd(cfg, args, o, state)),
48528
49618
  verbose: (args, o) => withConfig(state, o, (cfg) => verboseCmd(cfg, args, o, state)),
48529
49619
  context: (args, o) => withConfig(state, o, (cfg) => contextCmd(cfg, args, o, state)),
49620
+ security: (args, o) => withConfig(state, o, (cfg) => securityCmd(cfg, args, o, state)),
48530
49621
  session: (args, o) => sessionCmd(state, args, o),
48531
49622
  export: (args, o) => exportCmd(state, args, o)
48532
49623
  };
@@ -48586,6 +49677,22 @@ function contextCmd(cfg, args, out, state) {
48586
49677
  }
48587
49678
  return applyConfigWrite(cfg, "contextWindow", args[0], out, state);
48588
49679
  }
49680
+ function securityCmd(cfg, args, out, state) {
49681
+ const sub = args[0]?.trim().toLowerCase();
49682
+ if (!sub || sub === "status") {
49683
+ const flag = (v) => v ? t("reasoning.on") : t("reasoning.off");
49684
+ const s = cfg.security;
49685
+ out(`security · ${flag(s?.enabled)}`);
49686
+ out(`↳ bash ${flag(s?.bash.enabled)} · paths ${flag(s?.paths.enabled)} · network ${flag(s?.network.enabled)}`);
49687
+ out(`↳ contentScan ${flag(s?.contentScan.enabled)} · encryption ${flag(s?.sessionEncryption.enabled)}`);
49688
+ return;
49689
+ }
49690
+ if (args.length >= 2) {
49691
+ return applyConfigWrite(cfg, args[0], args.slice(1).join(" "), out, state);
49692
+ }
49693
+ out(`↳ ${t("web.security.unknown_sub", { sub: args[0] })}`);
49694
+ out(`usage: ${SECURITY_USAGE}`);
49695
+ }
48589
49696
  function sessionCmd(state, args, out) {
48590
49697
  const mgr = state.sessionManager;
48591
49698
  if (!mgr) {
@@ -48756,6 +49863,7 @@ var HELP = [
48756
49863
  { usage: "/reasoning [show|hide|on|off|level <lvl>]", descKey: "web.command.reasoning" },
48757
49864
  { usage: "/verbose <quiet|normal|verbose>", descKey: "web.command.verbose" },
48758
49865
  { usage: "/context [<tokens>]", descKey: "web.command.context" },
49866
+ { usage: "/security [status|<key> [value]]", descKey: "web.command.security" },
48759
49867
  { usage: "/session list | /session use <id>", descKey: "web.command.session" },
48760
49868
  { usage: "/export [md|json|jsonl]", descKey: "web.command.export" },
48761
49869
  { usage: "/memory [get|set|unset|find|forget]", descKey: "web.command.memory" },
@@ -49368,7 +50476,7 @@ async function persistAndReconfigure(s, config) {
49368
50476
  }
49369
50477
 
49370
50478
  // src/modules/webui/config-api.ts
49371
- function buildConfigRegistry() {
50479
+ function buildConfigRegistry(config) {
49372
50480
  return configDefs().map((def) => {
49373
50481
  const entry = {
49374
50482
  key: def.key,
@@ -49384,8 +50492,13 @@ function buildConfigRegistry() {
49384
50492
  entry.max = def.max;
49385
50493
  if (def.step !== undefined)
49386
50494
  entry.step = def.step;
49387
- if (def.readOnly)
50495
+ if (def.readOnly) {
49388
50496
  entry.readOnly = true;
50497
+ if (config)
50498
+ entry.value = def.get(config);
50499
+ }
50500
+ if (def.editor)
50501
+ entry.editor = def.editor;
49389
50502
  return entry;
49390
50503
  });
49391
50504
  }
@@ -49401,7 +50514,7 @@ function handleConfigGet(res, s) {
49401
50514
  }
49402
50515
  sendJson(res, 200, {
49403
50516
  config: redactConfigSecrets(s.config),
49404
- registry: buildConfigRegistry(),
50517
+ registry: buildConfigRegistry(s.config),
49405
50518
  webToken: maskToken(s.token)
49406
50519
  });
49407
50520
  }
@@ -49728,6 +50841,7 @@ function handleSessionsApi(req, res, reqUrl, s) {
49728
50841
 
49729
50842
  // src/modules/webui/settings-api.ts
49730
50843
  init_context_log();
50844
+ init_config();
49731
50845
  var MEMORY_CATEGORIES = ["conventions", "decisions", "errors", "facts"];
49732
50846
  function isCategory(value) {
49733
50847
  return MEMORY_CATEGORIES.includes(value);
@@ -49815,12 +50929,31 @@ function handleSkillsGet(res, s) {
49815
50929
  });
49816
50930
  sendJson(res, 200, { skills });
49817
50931
  }
50932
+ function mcpViewOptionals(cfg) {
50933
+ const out = {};
50934
+ if (cfg.transport)
50935
+ out.transport = cfg.transport;
50936
+ if (cfg.command)
50937
+ out.command = cfg.command;
50938
+ if (cfg.url)
50939
+ out.url = cfg.url;
50940
+ if (cfg.args)
50941
+ out.args = [...cfg.args];
50942
+ if (cfg.timeout !== undefined)
50943
+ out.timeout = cfg.timeout;
50944
+ if (cfg.enabled !== undefined)
50945
+ out.enabled = cfg.enabled;
50946
+ return out;
50947
+ }
49818
50948
  function mcpList(s) {
49819
50949
  const servers = s.config?.mcpServers ?? {};
49820
50950
  return Object.entries(servers).map(([key, cfg]) => ({
49821
50951
  id: key,
49822
50952
  name: cfg.name || key,
49823
- status: cfg.enabled === false ? "disabled" : "enabled"
50953
+ status: cfg.enabled === false ? "disabled" : "enabled",
50954
+ envKeys: cfg.env ? Object.keys(cfg.env) : [],
50955
+ headerKeys: cfg.headers ? Object.keys(cfg.headers) : [],
50956
+ ...mcpViewOptionals(cfg)
49824
50957
  }));
49825
50958
  }
49826
50959
  function handlePluginsGet(res, s) {
@@ -49875,38 +51008,349 @@ function handleMcpToggle(req, res, id, s) {
49875
51008
  readBodyError(req, res, err);
49876
51009
  });
49877
51010
  }
49878
- function handleSettingsApi(req, res, reqUrl, s) {
49879
- const p = reqUrl.pathname;
49880
- if (p === "/api/memory" && req.method === "GET") {
49881
- handleMemoryGet(res, s);
49882
- return true;
51011
+ var MCP_TRANSPORTS = ["stdio", "sse", "http"];
51012
+ function isRecord3(value) {
51013
+ return typeof value === "object" && value !== null && !Array.isArray(value);
51014
+ }
51015
+ function asStringArray(value) {
51016
+ if (!Array.isArray(value))
51017
+ return null;
51018
+ if (!value.every((x) => typeof x === "string"))
51019
+ return null;
51020
+ return [...value];
51021
+ }
51022
+ function asStringRecord(value) {
51023
+ if (!isRecord3(value))
51024
+ return null;
51025
+ const out = {};
51026
+ for (const [k, v] of Object.entries(value)) {
51027
+ if (typeof v !== "string")
51028
+ return null;
51029
+ out[k] = v;
49883
51030
  }
49884
- if (p === "/api/memory" && req.method === "POST") {
49885
- handleMemoryPost(req, res, s);
49886
- return true;
51031
+ return out;
51032
+ }
51033
+ function validTimeout(value) {
51034
+ return typeof value === "number" && Number.isInteger(value) && value >= 1000 && value <= 300000;
51035
+ }
51036
+ function validateMcpEntry(entry) {
51037
+ const transport = entry.transport ?? "stdio";
51038
+ if (!MCP_TRANSPORTS.includes(transport))
51039
+ return "invalid-transport";
51040
+ if (transport === "stdio") {
51041
+ if (!entry.command?.trim())
51042
+ return "command-required";
51043
+ } else if (!entry.url?.trim()) {
51044
+ return "url-required";
51045
+ }
51046
+ if (entry.timeout !== undefined && !validTimeout(entry.timeout))
51047
+ return "invalid-timeout";
51048
+ return null;
51049
+ }
51050
+ function applyFields(target, patch, appliers) {
51051
+ for (const [key, apply] of Object.entries(appliers)) {
51052
+ const value = patch[key];
51053
+ if (value === undefined)
51054
+ continue;
51055
+ const error = apply(target, value);
51056
+ if (error)
51057
+ return error;
49887
51058
  }
49888
- if (p.startsWith("/api/memory/") && req.method === "DELETE") {
49889
- const rest = p.slice("/api/memory/".length);
49890
- const slash = rest.indexOf("/");
49891
- const category = slash >= 0 ? decodeURIComponent(rest.slice(0, slash)) : "";
49892
- const nRaw = slash >= 0 ? decodeURIComponent(rest.slice(slash + 1)) : "";
49893
- handleMemoryDelete(res, category, nRaw, s);
49894
- return true;
51059
+ return null;
51060
+ }
51061
+ function setTrimmed(value, code, set, clear) {
51062
+ if (typeof value !== "string")
51063
+ return code;
51064
+ if (value.trim())
51065
+ set(value.trim());
51066
+ else
51067
+ clear();
51068
+ return null;
51069
+ }
51070
+ var MCP_FIELD_APPLIERS = {
51071
+ name: (next, v) => {
51072
+ if (typeof v !== "string" || !v.trim())
51073
+ return "name-required";
51074
+ next.name = v.trim();
51075
+ return null;
51076
+ },
51077
+ transport: (next, v) => {
51078
+ if (typeof v !== "string")
51079
+ return "invalid-transport";
51080
+ next.transport = v;
51081
+ return null;
51082
+ },
51083
+ command: (next, v) => setTrimmed(v, "invalid-command", (t2) => {
51084
+ next.command = t2;
51085
+ }, () => {
51086
+ delete next.command;
51087
+ }),
51088
+ url: (next, v) => setTrimmed(v, "invalid-url", (t2) => {
51089
+ next.url = t2;
51090
+ }, () => {
51091
+ delete next.url;
51092
+ }),
51093
+ args: (next, v) => {
51094
+ const args = asStringArray(v);
51095
+ if (!args)
51096
+ return "invalid-args";
51097
+ next.args = args;
51098
+ return null;
51099
+ },
51100
+ env: (next, v) => {
51101
+ const env3 = asStringRecord(v);
51102
+ if (!env3)
51103
+ return "invalid-env";
51104
+ next.env = env3;
51105
+ return null;
51106
+ },
51107
+ headers: (next, v) => {
51108
+ const headers = asStringRecord(v);
51109
+ if (!headers)
51110
+ return "invalid-headers";
51111
+ next.headers = headers;
51112
+ return null;
51113
+ },
51114
+ enabled: (next, v) => {
51115
+ if (typeof v !== "boolean")
51116
+ return "invalid-enabled";
51117
+ next.enabled = v;
51118
+ return null;
51119
+ },
51120
+ timeout: (next, v) => {
51121
+ if (!validTimeout(v))
51122
+ return "invalid-timeout";
51123
+ next.timeout = v;
51124
+ return null;
49895
51125
  }
49896
- if (p === "/api/skills" && req.method === "GET") {
49897
- handleSkillsGet(res, s);
49898
- return true;
51126
+ };
51127
+ function applyMcpPatch(next, patch) {
51128
+ return applyFields(next, patch, MCP_FIELD_APPLIERS);
51129
+ }
51130
+ function createMcpServer(config, input) {
51131
+ if (!isRecord3(input))
51132
+ return { ok: false, error: "invalid-input" };
51133
+ const name = typeof input.name === "string" ? input.name.trim() : "";
51134
+ if (!name)
51135
+ return { ok: false, error: "name-required" };
51136
+ if (!config.mcpServers)
51137
+ config.mcpServers = {};
51138
+ if (config.mcpServers[name])
51139
+ return { ok: false, error: "name-conflict" };
51140
+ const next = { name };
51141
+ const patchError = applyMcpPatch(next, { ...input, name });
51142
+ if (patchError)
51143
+ return { ok: false, error: patchError };
51144
+ const coherent = validateMcpEntry(next);
51145
+ if (coherent)
51146
+ return { ok: false, error: coherent };
51147
+ config.mcpServers[name] = next;
51148
+ return { ok: true, id: name };
51149
+ }
51150
+ function updateMcpServer(config, id, patch) {
51151
+ const current = config.mcpServers?.[id];
51152
+ if (!current)
51153
+ return { ok: false, error: "not_found" };
51154
+ if (!isRecord3(patch))
51155
+ return { ok: false, error: "invalid-input" };
51156
+ const next = { ...current };
51157
+ const patchError = applyMcpPatch(next, patch);
51158
+ if (patchError)
51159
+ return { ok: false, error: patchError };
51160
+ const coherent = validateMcpEntry(next);
51161
+ if (coherent)
51162
+ return { ok: false, error: coherent };
51163
+ config.mcpServers[id] = next;
51164
+ return { ok: true, id };
51165
+ }
51166
+ function deleteMcpServer(config, id) {
51167
+ if (!config.mcpServers?.[id])
51168
+ return { ok: false, error: "not_found" };
51169
+ delete config.mcpServers[id];
51170
+ return { ok: true, id };
51171
+ }
51172
+ function listLspServers(config) {
51173
+ const lsp = config.lsp ?? DEFAULT_LSP_CONFIG;
51174
+ return Object.entries(lsp.servers).map(([lang, srv]) => {
51175
+ const view = {
51176
+ lang,
51177
+ command: srv.command,
51178
+ timeout: srv.timeout ?? lsp.timeout,
51179
+ autoInstall: srv.autoInstall ?? false,
51180
+ enabled: lsp.enabled !== false && srv.enabled !== false
51181
+ };
51182
+ if (srv.args)
51183
+ view.args = [...srv.args];
51184
+ return view;
51185
+ });
51186
+ }
51187
+ var LSP_FIELD_APPLIERS = {
51188
+ enabled: (srv, v) => {
51189
+ if (typeof v !== "boolean")
51190
+ return "invalid-enabled";
51191
+ srv.enabled = v;
51192
+ return null;
51193
+ },
51194
+ command: (srv, v) => {
51195
+ if (typeof v !== "string" || !v.trim())
51196
+ return "invalid-command";
51197
+ srv.command = v.trim();
51198
+ return null;
51199
+ },
51200
+ args: (srv, v) => {
51201
+ const args = asStringArray(v);
51202
+ if (!args)
51203
+ return "invalid-args";
51204
+ srv.args = args;
51205
+ return null;
51206
+ },
51207
+ timeout: (srv, v) => {
51208
+ if (!validTimeout(v))
51209
+ return "invalid-timeout";
51210
+ srv.timeout = v;
51211
+ return null;
49899
51212
  }
49900
- if (p === "/api/plugins" && req.method === "GET") {
49901
- handlePluginsGet(res, s);
51213
+ };
51214
+ function applyLspPatch(srv, patch) {
51215
+ return applyFields(srv, patch, LSP_FIELD_APPLIERS);
51216
+ }
51217
+ function updateLspServer(config, lang, patch) {
51218
+ if (!isRecord3(patch))
51219
+ return { ok: false, error: "invalid-input" };
51220
+ if (!config.lsp)
51221
+ config.lsp = structuredClone(DEFAULT_LSP_CONFIG);
51222
+ const srv = config.lsp.servers[lang];
51223
+ if (!srv)
51224
+ return { ok: false, error: "not_found" };
51225
+ const patchError = applyLspPatch(srv, patch);
51226
+ if (patchError)
51227
+ return { ok: false, error: patchError };
51228
+ return { ok: true, lang };
51229
+ }
51230
+ function persistConfig2(s, config) {
51231
+ try {
51232
+ s.saveConfig?.(config);
49902
51233
  return true;
51234
+ } catch {
51235
+ return false;
51236
+ }
51237
+ }
51238
+ function handleConfigWrite(req, res, s, mutate, view) {
51239
+ if (!s.config) {
51240
+ sendJson(res, 503, { error: "config_unavailable" });
51241
+ return;
51242
+ }
51243
+ const config = s.config;
51244
+ readJsonBody(req, s.maxBodyBytes).then((rec) => {
51245
+ if (!rec) {
51246
+ sendJson(res, 400, { ok: false, error: "invalid JSON" });
51247
+ return;
51248
+ }
51249
+ const outcome = mutate(config, rec);
51250
+ if (!outcome.ok) {
51251
+ sendJson(res, outcome.status, { ok: false, error: outcome.error });
51252
+ return;
51253
+ }
51254
+ const persisted = persistConfig2(s, config);
51255
+ sendJson(res, 200, { ok: true, persisted, restartRequired: true, ...view(config, s) });
51256
+ }).catch((err) => {
51257
+ readBodyError(req, res, err);
51258
+ });
51259
+ }
51260
+ function mcpOutcome(result) {
51261
+ if (result.ok)
51262
+ return { ok: true };
51263
+ return { ok: false, status: result.error === "not_found" ? 404 : 400, error: result.error };
51264
+ }
51265
+ function handleMcpCreate(req, res, s) {
51266
+ handleConfigWrite(req, res, s, (config, rec) => mcpOutcome(createMcpServer(config, rec)), (_config, state) => ({ mcp: mcpList(state) }));
51267
+ }
51268
+ function handleMcpUpdate(req, res, id, s) {
51269
+ handleConfigWrite(req, res, s, (config, rec) => mcpOutcome(updateMcpServer(config, id, rec)), (_config, state) => ({ mcp: mcpList(state) }));
51270
+ }
51271
+ function handleMcpDelete(res, id, s) {
51272
+ if (!s.config) {
51273
+ sendJson(res, 503, { error: "config_unavailable" });
51274
+ return;
51275
+ }
51276
+ const result = deleteMcpServer(s.config, id);
51277
+ if (!result.ok) {
51278
+ sendJson(res, 404, { ok: false, error: result.error });
51279
+ return;
51280
+ }
51281
+ const persisted = persistConfig2(s, s.config);
51282
+ sendJson(res, 200, { ok: true, persisted, restartRequired: true, mcp: mcpList(s) });
51283
+ }
51284
+ function handleLspGet(res, s) {
51285
+ if (!s.config) {
51286
+ sendJson(res, 503, { error: "config_unavailable" });
51287
+ return;
51288
+ }
51289
+ sendJson(res, 200, { servers: listLspServers(s.config) });
51290
+ }
51291
+ function handleLspUpdate(req, res, lang, s) {
51292
+ handleConfigWrite(req, res, s, (config, rec) => {
51293
+ const result = updateLspServer(config, lang, rec);
51294
+ if (result.ok)
51295
+ return { ok: true };
51296
+ return { ok: false, status: result.error === "not_found" ? 404 : 400, error: result.error };
51297
+ }, (config) => ({ servers: listLspServers(config) }));
51298
+ }
51299
+ var SETTINGS_EXACT = {
51300
+ "GET /api/memory": (_req, res, _param, s) => handleMemoryGet(res, s),
51301
+ "POST /api/memory": (req, res, _param, s) => handleMemoryPost(req, res, s),
51302
+ "GET /api/skills": (_req, res, _param, s) => handleSkillsGet(res, s),
51303
+ "GET /api/plugins": (_req, res, _param, s) => handlePluginsGet(res, s)
51304
+ };
51305
+ var SETTINGS_PREFIX = [
51306
+ {
51307
+ method: "DELETE",
51308
+ prefix: "/api/memory/",
51309
+ handle: (_req, res, param, s) => {
51310
+ const slash = param.indexOf("/");
51311
+ handleMemoryDelete(res, slash >= 0 ? decodeURIComponent(param.slice(0, slash)) : "", slash >= 0 ? decodeURIComponent(param.slice(slash + 1)) : "", s);
51312
+ }
51313
+ },
51314
+ {
51315
+ method: "POST",
51316
+ prefix: "/api/mcp/",
51317
+ handle: (req, res, param, s) => handleMcpToggle(req, res, decodeURIComponent(param), s)
51318
+ },
51319
+ {
51320
+ method: "PUT",
51321
+ prefix: "/api/mcp/",
51322
+ handle: (req, res, param, s) => handleMcpUpdate(req, res, decodeURIComponent(param), s)
51323
+ },
51324
+ {
51325
+ method: "DELETE",
51326
+ prefix: "/api/mcp/",
51327
+ handle: (_req, res, param, s) => handleMcpDelete(res, decodeURIComponent(param), s)
51328
+ },
51329
+ {
51330
+ method: "PUT",
51331
+ prefix: "/api/lsp/",
51332
+ handle: (req, res, param, s) => handleLspUpdate(req, res, decodeURIComponent(param), s)
49903
51333
  }
49904
- if (p.startsWith("/api/mcp/") && req.method === "POST") {
49905
- handleMcpToggle(req, res, decodeURIComponent(p.slice("/api/mcp/".length)), s);
51334
+ ];
51335
+ function handleSettingsApi(req, res, reqUrl, s) {
51336
+ const p = reqUrl.pathname;
51337
+ const exact = SETTINGS_EXACT[`${req.method} ${p}`];
51338
+ if (exact) {
51339
+ exact(req, res, "", s);
49906
51340
  return true;
49907
51341
  }
51342
+ for (const route of SETTINGS_PREFIX) {
51343
+ if (req.method === route.method && p.startsWith(route.prefix)) {
51344
+ route.handle(req, res, p.slice(route.prefix.length), s);
51345
+ return true;
51346
+ }
51347
+ }
49908
51348
  return false;
49909
51349
  }
51350
+
51351
+ // src/modules/webui/providers-api.ts
51352
+ init_defaults();
51353
+
49910
51354
  // src/modules/webui/providers-view.ts
49911
51355
  init_presets();
49912
51356
  var LOCAL_PRESETS = [
@@ -49941,6 +51385,12 @@ function buildProviderViews(config) {
49941
51385
  view.contextWindow = e.contextWindow;
49942
51386
  if (e.priority !== undefined)
49943
51387
  view.priority = e.priority;
51388
+ if (e.maxCompletionTokens !== undefined)
51389
+ view.maxCompletionTokens = e.maxCompletionTokens;
51390
+ if (e.cache !== undefined)
51391
+ view.cache = { ...e.cache };
51392
+ if (e.retry !== undefined)
51393
+ view.retry = { ...e.retry };
49944
51394
  if (e.rateLimits) {
49945
51395
  view.rpm = e.rateLimits.maxRequestsPerMinute;
49946
51396
  view.parallel = e.rateLimits.maxParallelTasks;
@@ -49959,14 +51409,90 @@ function handleProvidersGet(res, s) {
49959
51409
  sendJson(res, 200, buildProviderViews(s.config));
49960
51410
  }
49961
51411
  function optionalInt(rec, key, min) {
51412
+ return optionalIntRange(rec, key, min, Number.MAX_SAFE_INTEGER);
51413
+ }
51414
+ function optionalIntRange(rec, key, min, max) {
49962
51415
  const v = rec[key];
49963
51416
  if (v === undefined || v === null || v === "")
49964
51417
  return;
49965
51418
  const n = typeof v === "number" ? v : Number(v);
49966
- if (!Number.isFinite(n) || !Number.isInteger(n) || n < min)
51419
+ if (!Number.isFinite(n) || !Number.isInteger(n) || n < min || n > max)
49967
51420
  return null;
49968
51421
  return n;
49969
51422
  }
51423
+ var CACHE_MECHANISMS = ["auto", "explicit", "local", "none"];
51424
+ var CACHE_REPORTS = ["openai", "deepseek", "anthropic", "ollama", "none"];
51425
+ var CACHE_FLAGS = [
51426
+ "sessionHeader",
51427
+ "requestCachePrompt",
51428
+ "requestPromptCacheKey",
51429
+ "requestSessionId",
51430
+ "requestCacheControl",
51431
+ "requestStreamUsage"
51432
+ ];
51433
+ function coerceFlag(v) {
51434
+ if (typeof v === "boolean")
51435
+ return v;
51436
+ if (v === 0 || v === 1)
51437
+ return v === 1;
51438
+ if (typeof v === "string") {
51439
+ const s = v.trim().toLowerCase();
51440
+ if (s === "true" || s === "1")
51441
+ return true;
51442
+ if (s === "false" || s === "0")
51443
+ return false;
51444
+ }
51445
+ return null;
51446
+ }
51447
+ function parseCache(v) {
51448
+ if (v === undefined || v === null)
51449
+ return;
51450
+ if (typeof v !== "object" || Array.isArray(v))
51451
+ return null;
51452
+ const rec = v;
51453
+ const out = {};
51454
+ if (rec.mechanism !== undefined) {
51455
+ if (typeof rec.mechanism !== "string" || !CACHE_MECHANISMS.includes(rec.mechanism))
51456
+ return null;
51457
+ out.mechanism = rec.mechanism;
51458
+ }
51459
+ if (rec.report !== undefined) {
51460
+ if (typeof rec.report !== "string" || !CACHE_REPORTS.includes(rec.report))
51461
+ return null;
51462
+ out.report = rec.report;
51463
+ }
51464
+ for (const flag of CACHE_FLAGS) {
51465
+ const fv = rec[flag];
51466
+ if (fv === undefined)
51467
+ continue;
51468
+ const b = coerceFlag(fv);
51469
+ if (b === null)
51470
+ return null;
51471
+ out[flag] = b;
51472
+ }
51473
+ return out;
51474
+ }
51475
+ function parseRetry(v) {
51476
+ if (v === undefined || v === null)
51477
+ return;
51478
+ if (typeof v !== "object" || Array.isArray(v))
51479
+ return null;
51480
+ const rec = v;
51481
+ const specs = [
51482
+ ["maxRetries", 0, 10],
51483
+ ["baseDelay", 0, 60000],
51484
+ ["maxDelay", 0, 300000]
51485
+ ];
51486
+ const out = {};
51487
+ for (const [key, min, max] of specs) {
51488
+ const n = optionalIntRange(rec, key, min, max);
51489
+ if (n === null)
51490
+ return null;
51491
+ if (n !== undefined)
51492
+ out[key] = n;
51493
+ }
51494
+ return out;
51495
+ }
49970
51496
  function parseProviderInput(rec) {
49971
51497
  const type2 = typeof rec.type === "string" ? rec.type.trim() : "";
49972
51498
  const baseUrl = typeof rec.baseUrl === "string" ? rec.baseUrl.trim() : "";
@@ -49985,6 +51511,15 @@ function parseProviderInput(rec) {
49985
51511
  const parallel = optionalInt(rec, "parallel", 1);
49986
51512
  if (contextWindow === null || priority === null || rpm === null || parallel === null)
49987
51513
  return null;
51514
+ const maxCompletionTokens = optionalIntRange(rec, "maxCompletionTokens", 512, 128000);
51515
+ if (maxCompletionTokens === null)
51516
+ return null;
51517
+ const cache = parseCache(rec.cache);
51518
+ if (cache === null)
51519
+ return null;
51520
+ const retry = parseRetry(rec.retry);
51521
+ if (retry === null)
51522
+ return null;
49988
51523
  const input = { type: type2, baseUrl };
49989
51524
  if (typeof rec.label === "string" && rec.label.trim())
49990
51525
  input.label = rec.label.trim();
@@ -50001,6 +51536,12 @@ function parseProviderInput(rec) {
50001
51536
  input.rpm = rpm;
50002
51537
  if (parallel !== undefined)
50003
51538
  input.parallel = parallel;
51539
+ if (maxCompletionTokens !== undefined)
51540
+ input.maxCompletionTokens = maxCompletionTokens;
51541
+ if (cache !== undefined)
51542
+ input.cache = cache;
51543
+ if (retry !== undefined)
51544
+ input.retry = retry;
50004
51545
  return input;
50005
51546
  }
50006
51547
  function mirrorLegacy(config, entry) {
@@ -50008,6 +51549,9 @@ function mirrorLegacy(config, entry) {
50008
51549
  config.provider.baseUrl = entry.baseUrl;
50009
51550
  if (entry.apiKey !== undefined)
50010
51551
  config.provider.apiKey = entry.apiKey;
51552
+ if (entry.maxCompletionTokens !== undefined) {
51553
+ config.provider.maxCompletionTokens = entry.maxCompletionTokens;
51554
+ }
50011
51555
  }
50012
51556
  function seededEntries(config) {
50013
51557
  const provider = config.provider;
@@ -50024,12 +51568,19 @@ function seededEntries(config) {
50024
51568
  }
50025
51569
  function upsertProvider(config, input) {
50026
51570
  const provider = config.provider;
51571
+ const fromLegacySeed = !Array.isArray(provider.entries) || provider.entries.length === 0;
50027
51572
  const entries = seededEntries(config);
50028
51573
  const name = input.label || input.type;
50029
51574
  if (providerNameTaken(entries, name, input.originalName)) {
50030
- return { ok: false, error: "name-conflict" };
51575
+ const loneSeeded = fromLegacySeed && entries.length === 1 && providerEntryName(entries[0]) === name;
51576
+ if (!loneSeeded || input.originalName) {
51577
+ return { ok: false, error: "name-conflict" };
51578
+ }
51579
+ }
51580
+ let idx = input.originalName ? entries.findIndex((e) => providerEntryName(e) === input.originalName || e.type === input.originalName) : -1;
51581
+ if (idx < 0 && fromLegacySeed && entries.length === 1 && providerEntryName(entries[0]) === name) {
51582
+ idx = 0;
50031
51583
  }
50032
- const idx = input.originalName ? entries.findIndex((e) => providerEntryName(e) === input.originalName || e.type === input.originalName) : -1;
50033
51584
  const entry = idx >= 0 ? { ...entries[idx] } : { type: input.type, baseUrl: input.baseUrl };
50034
51585
  entry.type = input.type;
50035
51586
  entry.baseUrl = input.baseUrl;
@@ -50041,6 +51592,18 @@ function upsertProvider(config, input) {
50041
51592
  entry.contextWindow = input.contextWindow;
50042
51593
  if (input.priority !== undefined)
50043
51594
  entry.priority = input.priority;
51595
+ if (input.maxCompletionTokens !== undefined)
51596
+ entry.maxCompletionTokens = input.maxCompletionTokens;
51597
+ if (input.cache !== undefined)
51598
+ entry.cache = { ...entry.cache ?? {}, ...input.cache };
51599
+ if (input.retry !== undefined) {
51600
+ const prev = entry.retry ?? {};
51601
+ entry.retry = {
51602
+ maxRetries: input.retry.maxRetries ?? prev.maxRetries ?? DEFAULTS.retry.maxRetries,
51603
+ baseDelay: input.retry.baseDelay ?? prev.baseDelay ?? DEFAULTS.retry.baseDelay,
51604
+ maxDelay: input.retry.maxDelay ?? prev.maxDelay ?? DEFAULTS.retry.maxDelay
51605
+ };
51606
+ }
50044
51607
  if (input.rpm !== undefined || input.parallel !== undefined) {
50045
51608
  const prev = entry.rateLimits ?? { maxRequestsPerMinute: 60, maxParallelTasks: 1 };
50046
51609
  entry.rateLimits = {
@@ -50245,7 +51808,7 @@ init_i18n();
50245
51808
  init_apply();
50246
51809
  init_answers();
50247
51810
  init_discovery();
50248
- function str2(rec, key) {
51811
+ function str3(rec, key) {
50249
51812
  const v = rec[key];
50250
51813
  return typeof v === "string" ? v.trim() : "";
50251
51814
  }
@@ -50255,16 +51818,16 @@ function positiveInt(rec, key) {
50255
51818
  return Number.isInteger(n) && n > 0 ? n : null;
50256
51819
  }
50257
51820
  function parseSetupAnswers(rec) {
50258
- const provider = str2(rec, "provider");
50259
- const apiBase = str2(rec, "apiBase");
50260
- const model = str2(rec, "model");
51821
+ const provider = str3(rec, "provider");
51822
+ const apiBase = str3(rec, "apiBase");
51823
+ const model = str3(rec, "model");
50261
51824
  if (!provider || !apiBase || !model)
50262
51825
  return null;
50263
51826
  const contextWindow = positiveInt(rec, "contextWindow");
50264
51827
  const maxToolIterations = positiveInt(rec, "maxToolIterations");
50265
51828
  if (contextWindow === null || maxToolIterations === null)
50266
51829
  return null;
50267
- const locale = str2(rec, "locale");
51830
+ const locale = str3(rec, "locale");
50268
51831
  if (!SETUP_LANGUAGES.some((l) => l.value === locale))
50269
51832
  return null;
50270
51833
  const flags = ["securityBashBlock", "securityFlagsBlock", "securityPathsRestrict"];
@@ -50308,12 +51871,12 @@ function handleSetupModels(req, res, s) {
50308
51871
  sendJson(res, 400, { ok: false, error: "invalid JSON" });
50309
51872
  return;
50310
51873
  }
50311
- const baseUrl = str2(rec, "baseUrl");
51874
+ const baseUrl = str3(rec, "baseUrl");
50312
51875
  if (!baseUrl) {
50313
51876
  sendJson(res, 400, { ok: false, error: "invalid-base-url" });
50314
51877
  return;
50315
51878
  }
50316
- const models = await fetchProviderModels(baseUrl, str2(rec, "apiKey"));
51879
+ const models = await fetchProviderModels(baseUrl, str3(rec, "apiKey"));
50317
51880
  sendJson(res, 200, { models });
50318
51881
  }).catch((err) => {
50319
51882
  readBodyError(req, res, err);
@@ -50325,13 +51888,13 @@ function handleSetupTest(req, res, s) {
50325
51888
  sendJson(res, 400, { ok: false, error: "invalid JSON" });
50326
51889
  return;
50327
51890
  }
50328
- const baseUrl = str2(rec, "baseUrl");
50329
- const model = str2(rec, "model");
51891
+ const baseUrl = str3(rec, "baseUrl");
51892
+ const model = str3(rec, "model");
50330
51893
  if (!baseUrl || !model) {
50331
51894
  sendJson(res, 400, { ok: false, error: "invalid-test-request" });
50332
51895
  return;
50333
51896
  }
50334
- const ok = await testProviderChat(baseUrl, str2(rec, "apiKey"), model);
51897
+ const ok = await testProviderChat(baseUrl, str3(rec, "apiKey"), model);
50335
51898
  sendJson(res, 200, { ok });
50336
51899
  }).catch((err) => {
50337
51900
  readBodyError(req, res, err);
@@ -50343,7 +51906,7 @@ function handleSetupLocale(req, res, s) {
50343
51906
  sendJson(res, 400, { ok: false, error: "invalid JSON" });
50344
51907
  return;
50345
51908
  }
50346
- const locale = str2(rec, "locale");
51909
+ const locale = str3(rec, "locale");
50347
51910
  if (!SETUP_LANGUAGES.some((l) => l.value === locale)) {
50348
51911
  sendJson(res, 400, { ok: false, error: "unsupported-locale" });
50349
51912
  return;
@@ -50484,7 +52047,9 @@ var API_ROUTES = {
50484
52047
  },
50485
52048
  "GET /api/models": (_req, res, s) => handleModelsGet(res, s),
50486
52049
  "POST /api/command": (req, res, s) => handleCommandPost(req, res, s),
50487
- "POST /api/interrupt": (_req, res, s) => handleInterruptPost(res, s)
52050
+ "POST /api/interrupt": (_req, res, s) => handleInterruptPost(res, s),
52051
+ "POST /api/mcp": (req, res, s) => handleMcpCreate(req, res, s),
52052
+ "GET /api/lsp": (_req, res, s) => handleLspGet(res, s)
50488
52053
  };
50489
52054
  var API_GROUPS = [handleSetupApi, handleSessionsApi, handleSettingsApi, handleProvidersApi, handleFileApi];
50490
52055
  function handleApi(req, res, reqUrl, s) {