Skip to content

feat(config): expose FORGE_* env vars via :config-env command#2704

Open
chengyixu wants to merge 1 commit intoantinomyhq:mainfrom
chengyixu:feat/config-env-command
Open

feat(config): expose FORGE_* env vars via :config-env command#2704
chengyixu wants to merge 1 commit intoantinomyhq:mainfrom
chengyixu:feat/config-env-command

Conversation

@chengyixu
Copy link
Copy Markdown

Fixes #2638

Problem

Many Forge configuration knobs (retry limits, HTTP timeouts, tool timeouts, file size limits, tuning parameters) are only discoverable by reading source code. Changing them requires manually editing .forge.toml or setting environment variables — there is no in-shell way to list what is configurable or to set a value interactively.

Solution

This PR adds a :config-env (:ce) command and the corresponding CLI plumbing so users can browse, inspect, and set all FORGE_* environment variables without leaving the terminal.

CLI changes

Command Behaviour
forge config get env Lists all 40+ known FORGE_* vars with current values, defaults, and descriptions
forge config get env KEY Shows the current value of a single variable
forge config set env KEY VALUE Writes the value to ~/.forge/.forge.toml and applies immediately (no restart)

ZSH changes

  • :config-env / :ce — opens an fzf picker populated by forge config get env; selecting a variable prompts for a new value and calls forge config set env automatically
  • Registered in built_in_commands.json so it appears in :help and tab completion

Architecture

  • env_registry module in forge_config — a static catalogue mapping each FORGE_* env var to its TOML key, default value, and description. This is the single source of truth for discoverability.
  • Config persistence — values are written to the global ~/.forge/.forge.toml (not .env), consistent with the existing config system and ForgeConfig::write() path.
  • Type-aware TOML serialization — values are parsed as bool, integer, float, or string before writing, so the TOML file stays well-typed.
  • Immediate effect — the env var is also set in the running process via std::env::set_var so changes take effect without restarting.

Example

# List all configurable variables
$ forge config get env
ENVIRONMENT VARIABLES
  FORGE_TOOL_TIMEOUT_SECS   300  (default)  # Max seconds a tool call is allowed to run
  FORGE_MAX_SEARCH_LINES    1000  (default)  # Max lines returned by file search
  ...

# Get a specific variable
$ forge config get env FORGE_TOOL_TIMEOUT_SECS
FORGE_TOOL_TIMEOUT_SECS (not set, default: 300)

# Set a variable (writes to .forge.toml, applies immediately)
$ forge config set env FORGE_TOOL_TIMEOUT_SECS 60
● FORGE_TOOL_TIMEOUT_SECS  set to '60' in /home/user/forge/.forge.toml

# Or interactively via ZSH
:ce   # Opens fzf picker → select variable → enter value

Variables exposed

40+ FORGE_* variables covering: tool timeouts, file size limits, search limits, stdout truncation, HTTP/TLS config, retry settings, semantic search parameters, tuning parameters (temperature, top_p, top_k, max_tokens), and more.

Files changed

File Change
crates/forge_config/src/env_registry.rs New: static registry of all FORGE_* variables
crates/forge_config/src/lib.rs Export new module
crates/forge_main/src/cli.rs Add Env variants to ConfigSetField and ConfigGetField
crates/forge_main/src/ui.rs Implement handle_config_env_set and handle_config_env_get handlers
crates/forge_main/src/built_in_commands.json Register :config-env command
crates/forge_main/Cargo.toml Add forge_config and toml_edit dependencies
shell-plugin/lib/dispatcher.zsh Route :config-env / :ce to action handler
shell-plugin/lib/actions/config.zsh New _forge_action_config_env function with fzf picker

Test plan

  • All 245 forge_main library tests pass
  • All 11 forge_config tests pass (including 4 new env_registry tests)
  • All 75 CLI parsing tests pass
  • Zero clippy warnings
  • cargo check succeeds

Co-Authored-By: ForgeCode noreply@forgecode.dev

Add a discoverable way to browse, inspect, and set all FORGE_*
environment variables without manually editing config files.

CLI changes:
- `forge config get env` lists all known FORGE_* vars with current
  values, defaults, and descriptions
- `forge config get env KEY` shows a single variable's current value
- `forge config set env KEY VALUE` writes the value to ~/.forge/.forge.toml
  and applies it immediately (no restart needed)

ZSH changes:
- `:config-env` / `:ce` opens an fzf picker of all configurable
  variables; selecting one prompts for a new value and persists it

Implementation:
- New `env_registry` module in forge_config with a static catalogue of
  40+ FORGE_* variables mapped to their TOML keys, defaults, and
  descriptions
- Values are written to the global .forge.toml config (not .env) for
  consistency with the existing config system
- Type-aware TOML serialization (bool, int, float, string)

Fixes antinomyhq#2638

Co-Authored-By: ForgeCode <noreply@forgecode.dev>
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 26, 2026

CLA assistant check
All committers have signed the CLA.

};

// Parse the existing TOML document for editing
let mut doc: toml_edit::DocumentMut = existing.parse().unwrap_or_default();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data Loss: Silent Parse Error Handling

If the existing .forge.toml contains invalid TOML syntax, unwrap_or_default() silently creates an empty document and overwrites the file, destroying all existing configuration.

Fix: Return the parse error instead of silently discarding it:

let mut doc: toml_edit::DocumentMut = existing.parse()
    .map_err(|e| anyhow::anyhow!("Failed to parse existing config file: {e}"))?;
Suggested change
let mut doc: toml_edit::DocumentMut = existing.parse().unwrap_or_default();
let mut doc: toml_edit::DocumentMut = existing.parse().map_err(|e| anyhow::anyhow!("Failed to parse existing config file: {e}"))?;

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

This comment came from an experimental review—please leave feedback if it was helpful/unhelpful. Learn more about experimental comments here.

@chengyixu
Copy link
Copy Markdown
Author

recheck

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Expose all env variables via a :config-* command

2 participants