Skip to content

Configuration

Eshan Roy edited this page Jun 16, 2026 · 2 revisions

Configuration

M31A is configured via a TOML file at ~/.m31a/config.toml. Override the path with the M31A_CONFIG environment variable.

Full Configuration Reference

# ============================================================================
# Provider Configuration
# ============================================================================
[provider]
default = "openrouter"          # Active provider: "openrouter" or "zen"
auto_fallback = true            # Auto-switch to healthy provider on failure

[provider.openrouter]
api_key = ""                    # OpenRouter API key (prefer keychain)

[provider.zen]
api_key = ""                    # Zen API key (prefer keychain)

# Custom base URLs for self-hosted or proxied gateways
# openrouter_base_url = ""
# zen_base_url = ""

# HTTP headers for OpenRouter
# openrouter_referer = "https://github.com/eshanized/M31A"
# openrouter_title = "M31A"

# ============================================================================
# Model Configuration
# ============================================================================
[model]
default = ""                    # Default model ID (empty = prompt at startup)
context_warning_threshold = 0.8 # Warn when context usage exceeds this (0.0-1.0)
show_thinking_by_default = false
auto_collapse_tools = false
auto_arbitrage = false          # Auto-switch to cheapest model per task
arbitrage_threshold = 0.1       # Minimum savings ratio to trigger switch
default_context_length = 128000 # Fallback context length when provider doesn't return one
token_ema_alpha = 0.3          # Token estimator EMA calibration rate

# ============================================================================
# UI Configuration
# ============================================================================
[ui]
theme = "dark"                  # "dark", "light", or "auto"
compact_mode = false
show_token_usage = false
show_cost_estimate = true
max_iterations = 0              # 0 = unlimited workflow iterations
leader_key = "ctrl+x"           # Leader key for chord shortcuts
leader_timeout_ms = 1000        # Leader key timeout
sidebar_width_threshold = 120   # Min terminal width for sidebar auto-show
discuss_timeout = 300           # Discuss Q&A timeout in seconds
thinking_max_lines = 20         # Max lines for thinking block
permission_modal_width = 60     # Permission modal width in columns
sidebar_width = 42              # Sidebar width in columns
max_message_history = 1000      # Max message history entries
fallback_banner_timeout_secs = 15
default_log_lines = 20
session_list_limit = 10         # Max sessions in resume screen
thinking_opacity = 0.6
frecent_history_size = 100      # Frecent history max entries

# Theme and Colors
# accent_color = ""
# custom_background = ""
# border_style = ""

# Typography
# bold_headers = true
# italic_thinking = false
# tab_width = 4

# Layout
# sidebar_position = "right"    # "left" or "right"
# sidebar_auto_show = true
# card_padding = 1
# welcome_screen = true

# Animation
# animation_speed = "normal"    # "fast", "normal", "slow"
# spinner_style = ""
# transition_style = ""
# breathing_effects = false
# logo_animation = true

# Status Bar
# status_bar_style = ""
# status_bar_position = "bottom"
# show_spinner_in_status = true

# Tool Cards
# tool_card_style = ""
# tool_output_max_lines = 20
# syntax_highlight = true

# Toasts
# toast_position = "top-right"
# toast_duration_secs = 10
# toast_max_visible = 3

# ============================================================================
# Permissions Configuration
# ============================================================================
[permissions]
default_mode = "ask"            # "ask", "allow", or "deny"
timeout_seconds = 300           # Permission modal timeout

# Permission rules (evaluated in order)
# [[permissions.rules]]
# tool = "Bash"
# pattern = "rm -rf"
# risk_level = "destructive"
# action = "deny"

# [[permissions.rules]]
# tool = "Bash"
# pattern = "go test"
# risk_level = "safe"
# action = "allow"

# Per-agent permission profiles
# [permissions.agents.build]
# default_action = "allow"
# [[permissions.agents.build.rules]]
# tool = "Bash"
# pattern = "go build"
# action = "allow"

# ============================================================================
# Features Configuration
# ============================================================================
[features]
auto_backup = true              # Auto-backup files before edit/write
resume_on_startup = false       # Auto-resume most recent session
workflow_mode = ""              # "auto", "full", "fast", or "direct"
model_cache_ttl_minutes = 5     # Model cache TTL
model_cache_stale_hours = 24    # Stale cache fallback TTL
healthcheck_live_ms = 500       # Health check "live" threshold
healthcheck_slow_ms = 2000      # Health check "slow" threshold
session_id_length = 8           # Session ID length in hex chars
max_recent_models = 10          # Max recent models to remember
session_retention_days = 30     # Session retention period
health_check_timeout_secs = 10  # Health check timeout
rate_limit_backoff_secs = 120   # Rate limit backoff
budget_limit_usd = 0            # Per-session budget limit (0 = unlimited)

# ============================================================================
# Ledger Configuration
# ============================================================================
[ledger]
enabled = true                  # Enable cross-session learning ledger
max_entries = 100               # Max ledger entries

# ============================================================================
# Agents Configuration (per-phase model assignment)
# ============================================================================
[agents]
default = ""                    # Global agent default model
plan = ""                       # Model for Plan phase
execute = ""                    # Model for Execute phase
verify = ""                     # Model for Verify phase
ship = ""                       # Model for Ship phase
discuss = ""                    # Model for Discuss phase

# ============================================================================
# Git Configuration
# ============================================================================
[git]
commit_prefix = "feat"          # Default commit prefix
fix_prefix = "fix"              # Prefix for fix commits
ship_prefix = "ship"            # Prefix for ship commits
# user_name = ""                # Git user.name override
# user_email = ""               # Git user.email override

# ============================================================================
# Verify Configuration
# ============================================================================
[verify]
# build_command = ""            # Custom build command (empty = auto-detect)
# test_command = ""             # Custom test command (empty = auto-detect)

# ============================================================================
# Tools Configuration
# ============================================================================
[tools]
max_glob_results = 1000
max_grep_results = 100
bash_kill_grace_secs = 5
max_backups_per_file = 10
webfetch_max_redirects = 5
# webfetch_user_agent = ""
# skip_dirs = ["node_modules", "vendor"]
# websearch_base_url = ""       # Custom SearXNG instance URL
# websearch_enabled = true

Environment Variables

Variable Description
M31A_CONFIG Override config file path
OPENROUTER_API_KEY OpenRouter API key (alternative to keychain)
ZEN_API_KEY Zen API key (alternative to keychain)

Config Hot-Reload

M31A watches the config file for changes (5-second polling interval via fsnotify). When the file changes, the config is reloaded and applied at runtime without restarting.

Source: internal/config/loader.go

Project Context Detection

M31A detects project type by scanning for marker files up to 3 parent directories deep (MaxProjectConfigDepth):

Marker File Detected Type
go.mod Go project
package.json Node.js project
Cargo.toml Rust project
pyproject.toml / requirements.txt Python project
Gemfile Ruby project

Source: internal/config/project_context.go

Clone this wiki locally