For AI agents: the complete documentation index is available at /en/llms.txt, the full documentation bundle is available at /en/llms-full.txt, and this page is available as Markdown at /en/guide/start/configuration/config.md.
  • English
  • config.toml

    Controls Hunea's behavior. Generally you don't need much configuration — the defaults work for most use cases. Here are the defaults (what you see below is the default) and configurable examples:

    # When both exist, project-level configuration overrides user-level.
    # After modifying configuration, you need to restart Hunea for changes to take effect.
    #
    # Additional note: if there's a `portable.marker` in `.hunea/` of your workspace, it enters portable mode —
    # only reads configuration/sessions from this workspace and doesn't overlay global `~/.config/hunea/`.
    # If the global configuration directory isn't available on first launch, precheck may guide you to create this marker.
    
    [tui]
    # `motion` controls decorative animations in the TUI.
    # - "full": enable all animations, this is the default.
    # - "reduced": disable entrance, toast transitions, stream activity tick, and tool marker blinking;
    #   the toast display duration is still preserved.
    motion = "full"
    
    # `scroll_animation` controls the smooth scrolling feel for the mouse wheel (frame stepping + acceleration for fast consecutive scrolling).
    # - "off": disable smooth scrolling, wheel returns to instantaneous jumps of 3 lines per notch, no acceleration.
    # - "snappy": close to instantaneous, only softens large scrolls.
    # - "fast": fast convergence, minimal animation.
    # - "smooth": balanced setting, this is the default.
    # - "gentle": longer sliding.
    # - "glide": longest sliding.
    # Note: when `motion = "reduced"`, scrolling is instantaneous regardless of this setting.
    scroll_animation = "smooth"
    
    # `diff_display` controls the coloring scope of tool-activity diffs and whether hunk rows render in the main view.
    # - "full_line": foreground + full-line background across the widget width + inline emphasis; the default.
    # - "content": background only on the gutter and cells that have text; trailing whitespace is not colored; inline emphasis retained.
    # - "text": no background or reversal; Insert/Delete still use line-level foreground color; emphasized segments are Bold only.
    # - "summary": the main view keeps only the header's +N/−M counts and renders no hunks; the `ctrl+t` overlay still shows the full diff as full_line.
    diff_display = "full_line"
    
    # `command_menu_mode` controls how the command menu (slash commands) is triggered.
    # - "slash": only triggers the inline slash command menu when the composer starts with `/`; this is the default.
    # - "floating": `/` no longer triggers the menu (treated as plain text); open the floating command menu with `Ctrl+O` instead.
    # - "both": both work at once; the inline `/` menu and the `Ctrl+O` floating menu don't interfere with each other.
    command_menu_mode = "slash"
    
    # `command_menu_rows` controls how many command rows the `Ctrl+O` floating command menu shows at once;
    # extra commands scroll, with a scrollbar on the right of the popup.
    # Range 7..21, default 7 rows.
    command_menu_rows = 7
    
    # Possible values:
    # `user_input_style` controls the display style for "in-progress user input" and "sent user messages".
    # - "cx": current framed style. Composer and user messages get a surface frame when the window is tall enough.
    # - "cc": full-line colored compact style. Disables top/bottom surface frames, but keeps full-line user message background.
    # - "ms": original old theme. User messages are colored by content bounds, no full-line padding, and no surface frame.
    user_input_style = "cx"
    
    # `status_line` controls what information to display in the status line under the input box.
    # The order directly affects left-to-right display order.
    # Currently supported values:
    # - "git-branch": branch name of the Git repository the current working directory is in
    # - "current-dir": short path of the current working directory, home prefix abbreviated to ~
    # - "current-model": currently selected model, formatted as provider/model
    # - "throughput": LLM tokens per second output for the last successful request, e.g. 139tps
    # - "latency": time-to-first-token for the last successful request, e.g. 0.53s
    # - "context-used": percentage of context used after the last successful request, e.g. Context 42% used
    # - "context-remaining": percentage of context remaining after the last successful request, e.g. Context 58% left
    #
    # If not configured, no status line is shown; if configured but none of the items can resolve to displayable content,
    # the status line remains hidden.
    # status_line = ["git-branch"]
    
    # `status_line_2` uses the same array format as `status_line`, for configuring a second status line.
    # If the second line configures the same items as the first line, the first line has priority and the second line automatically skips duplicates.
    # If not configured or explicitly written as [], no second line is shown.
    # status_line_2 = ["current-dir"]
    
    # `external_editor` controls the external editor command opened by Ctrl+G.
    # Use native TOML array to express argv, for example:
    # - ["code", "--wait"]
    # - ["cursor", "--wait"]
    # - ["zed", "--wait"]
    # - ["subl", "-w"]
    # - ["open", "-W", "-n", "-t"]
    # - ["nvim"]
    #
    # For GUI editors like VS Code, Cursor, Zed, Sublime Text,
    # you need to explicitly include the "wait until closed" parameter; otherwise Hunea returns to the TUI as soon as the editor process starts.
    # For macOS `open`, you also need both `-W` and `-n`.
    #
    # If not configured or explicitly written as [], it falls back to auto-detection:
    # tries VISUAL, EDITOR, then common platform editor commands in order.
    # external_editor = ["code", "--wait"]
    
    # `show_external_editor_helper` controls whether to show the brief
    # "ctrl+g to edit in …" hint when the draft is multi-line.
    # Enabled by default; if you're already familiar with the Ctrl+G workflow, you can turn it off to reduce noise.
    show_external_editor_helper = true
    
    # `copy_on_mouse_selection_release` controls whether to automatically copy the selection when you release the mouse
    # button after dragging to create a selection.
    # Disabled by default; enabling gives the "select to copy" feel familiar from some terminals.
    copy_on_mouse_selection_release = false
    
    # `swap_enter_and_send` controls whether to swap the key semantics of "newline" and "send message".
    # Disabled by default; when enabled:
    # - Enter inserts a newline
    # - Ctrl+J and Shift+Enter send the message
    swap_enter_and_send = false
    
    # `ctrl_c_clears_input` controls whether a single Ctrl+C directly clears the draft when there's an unsent draft in the input box.
    # Enabled by default; when disabled, Ctrl+C reverts to exit confirmation semantics.
    ctrl_c_clears_input = true
    
    # `composer_undo_limit` controls how many draft snapshots Ctrl+Z can undo in the input box.
    # Only stored in the current TUI process, not written to session or config; the Ctrl+Y kill buffer still only keeps the latest kill.
    # Range 1..200, default 50.
    composer_undo_limit = 50
    
    # `message_history_limit` controls the maximum number of global message history entries (cross-project).
    # Specifically affects the capacity limit of the /resend interface.
    # Range 100..1000, default 100.
    message_history_limit = 100
    
    # `esc_interrupt_presses` controls how many consecutive presses of Esc are needed
    # to interrupt the current native request when a conversation turn is running.
    # Allowed values 1, 2, 3; default 2.
    esc_interrupt_presses = 2
    
    # `show_esc_interrupt_hint` controls whether to show an interrupt hint like
    # `esc 2x to interrupt` on the waiting line. Enabled by default.
    show_esc_interrupt_hint = true
    
    # `file_picker_popup_height` controls the total height of the @ aggregated search popup (including the blank row and footer).
    # Files and skills share this popup; it always uses full terminal width, vertically anchored at the @ position, flipping when space is tight.
    # Range 3..21, default 9 rows.
    file_picker_popup_height = 9
    
    # `branch_picker_list_rows` controls how many visible branches the conversation tree branch picker popup shows.
    # Range 3..14, default 7 rows.
    branch_picker_list_rows = 7
    
    # `print_transcript_on_exit` controls whether to replay and print the current conversation
    # to the terminal scrollback after exiting TUI.
    # This feature hasn't been maintained in a long time, it's recommended to keep it disabled by default.
    print_transcript_on_exit = false
    
    # `show_reasoning_content` controls whether to show the reasoning / thinking content returned by thinking models
    # before the assistant message body.
    # Disabled by default; when disabled, reasoning is still counted towards waiting line tokens and shows
    # a temporary `thinking` state during reasoning streaming.
    # That means, by default thinking content isn't shown, and you won't see it in the ctrl+t interface either —
    # but /tree still preserves the thinking content.
    show_reasoning_content = false
    
    # `reasoning_content_display` controls the default display state of reasoning content in the transcript
    # when `show_reasoning_content = true`.
    # If not configured, `show_reasoning_content = true` defaults to `expanded`.
    # `expanded-simplified` is a compact variant of `expanded` for long content: short content shows fully;
    # long content keeps the first and last 4 lines, with `… +N lines (ctrl + t to view transcript)` in the middle.
    # When you enter the transcript overlay with Ctrl+T, the full content is shown.
    # Allowed values: `collapsed`, `expanded`, `expanded-simplified`, `snippet`.
    reasoning_content_display = "collapsed"
    
    # Controls which backtracking mode to use when you double-press Esc with an empty input box and no streaming output,
    # and whether the slash menu shows /tree or /sends-back (they don't both appear).
    #
    # Default coarse:
    # - double Esc → edit/resend by user message round (truncate after that message and refill content into input box)
    # - menu shows /tree
    # When configured to entry:
    # - double Esc → open /tree (precise session node backtracking / create branch)
    # - menu shows /sends-back (keeps the "edit user message" entry)
    esc_rewind_mode = "coarse"
    
    # `keyboard_enhancement` controls whether to enable kitty keyboard protocol for enhanced keybindings.
    # - "auto": automatically detects based on environment (e.g. disables in VSCode terminal inside WSL), this is the default.
    # - "on": force enable.
    # - "off": force disable.
    # Most cases can keep auto; if combinations or modifier keys behave strangely, you can explicitly disable and try again.
    keyboard_enhancement = "auto"
    
    [runtime]
    # `request_retry_attempts` controls how many retries are allowed after a failed runtime request.
    # This strategy is used by current native chat.
    # Allowed values 1..10; default 3.
    request_retry_attempts = 3
    
    # `request_retry_delays` controls how many seconds to wait before each retry.
    # Each value ranges from 1..1800.
    # For example [1, 3, 5] means wait 1s before the first retry, 3s before the second,
    # 5s before the third. If the list is shorter than request_retry_attempts, the last value is reused to fill in.
    request_retry_delays = [1, 2, 3]
    
    # `request_timeout_seconds` controls the idle timeout (in seconds) for **a single provider HTTP request**:
    # it limits connection waiting and the idle interval between adjacent chunks in a streaming response; the timer resets when data is received.
    # It **does not** limit the total duration of an entire turn. As long as data keeps arriving during the response, it won't interrupt just because total time exceeds 120s.
    # After timeout, it enters the retry flow above; each retry gets a full fresh idle timeout.
    # Allowed values 1..7200; default 120.
    request_timeout_seconds = 120
    
    # `tool_max_turns` controls the maximum number of agent multi-turn tool calling rounds.
    # Default is unlimited; set to a positive integer to terminate the request after exceeding this number of rounds.
    # tool_max_turns = 32
    
    # `allow_managed_rg` records whether to allow Hunea to download, verify, and install a pinned
    # version of `rg` when neither system PATH nor a bundled binary is available.
    # Omitted means ask when a download is actually needed; true allows download/rebuild; false disables managed ripgrep.
    # When false, Hunea still prefers the PATH/bundled ripgrep; it falls back to the Rust backend only when neither is available.
    # allow_managed_rg = true
    
    [debug]
    # `enabled` controls whether to show slash commands only for local TUI debugging.
    # Disabled by default; when enabled, it shows temporary debugging entries like `/tool-debug`.
    # This is actually a feature I've neglected, and I'll consider removing or improving it later.
    enabled = false

    The getting started page also has my personal recommended minimal configuration, see Getting Started.

    Related pages: