Config
The config module loads settings from .towl.toml, merges environment variables, and provides the init command for generating default configuration.
TowlConfig
#![allow(unused)]
fn main() {
pub struct TowlConfig {
pub parsing: ParsingConfig,
pub github: GitHubConfig,
pub llm: LlmConfig,
}
}
TowlConfig::load
#![allow(unused)]
fn main() {
impl TowlConfig {
pub fn load(path: Option<&PathBuf>) -> Result<Self, TowlConfigError>;
}
}
Loads configuration with this precedence:
- Built-in defaults
- Config file resolved as: explicit
pathargument >TOWL_CONFIGenv var >.towl.toml - Git remote auto-detection for owner/repo
- Environment variable overrides (
TOWL_GITHUB_*,TOWL_LLM_*)
If no config file exists, defaults are used without error.
init
#![allow(unused)]
fn main() {
pub async fn init(path: &Path, force: bool) -> Result<(), TowlConfigError>
}
Creates a .towl.toml file at the given path. Validates that a GitHub git remote exists but does not write owner/repo to the file (they are always detected at runtime).
- Fails if the file already exists (unless
forceistrue) - Validates the path for traversal attacks
- Serializes
ParsingConfigandLlmConfigdefaults to TOML
ParsingConfig
#![allow(unused)]
fn main() {
pub struct ParsingConfig {
pub file_extensions: HashSet<String>,
pub exclude_patterns: Vec<String>,
pub include_context_lines: usize,
pub comment_prefixes: Vec<String>,
pub todo_patterns: Vec<String>,
pub function_patterns: Vec<String>,
}
}
All fields have defaults via #[serde(default)]:
| Field | Default |
|---|---|
file_extensions | rs, toml, json, yaml, yml, sh, bash |
exclude_patterns | target/*, .git/* |
include_context_lines | 10 |
comment_prefixes | //, ^\s*#, /\*, ^\s*\* |
todo_patterns | TODO:, FIXME:, HACK:, NOTE:, BUG: (case-insensitive) |
function_patterns | Rust, Python, JS, Java/C#, Go patterns |
Each pattern array is limited to MAX_CONFIG_PATTERNS (100) entries.
GitHubConfig
#![allow(unused)]
fn main() {
pub struct GitHubConfig {
pub token: SecretString,
pub owner: Owner,
pub repo: Repo,
pub rate_limit_delay_ms: u64,
}
}
tokenis stored assecrecy::SecretStringand masked in debug/display outputownerandrepoare auto-detected fromgit remote get-url originat runtime (not serialised to config)rate_limit_delay_msadds a delay between GitHub API calls (default: 1000ms)
Environment Variable Overrides
| Variable | Overrides |
|---|---|
TOWL_CONFIG | DEFAULT_CONFIG_PATH (overridden by explicit path argument) |
TOWL_GITHUB_TOKEN | – (env-only) |
TOWL_GITHUB_OWNER | git remote detection |
TOWL_GITHUB_REPO | git remote detection |
Owner / Repo
Validated newtype wrappers providing type safety:
#![allow(unused)]
fn main() {
pub struct Owner(String);
pub struct Repo(String);
}
try_new
#![allow(unused)]
fn main() {
pub fn try_new(s: impl Into<String>) -> Result<Self, TowlConfigError>
}
Constructs a new Owner or Repo, rejecting values exceeding MAX_CONFIG_STRING_LENGTH (512 characters).
Errors:
ConfigValueTooLong– Value exceeds 512 characters
Both also implement:
Display,Default,Debug,Clone,PartialEq,EqSerialize,Deserialize
LlmConfig
#![allow(unused)]
fn main() {
pub struct LlmConfig {
pub provider: String,
pub model: String,
pub base_url: Option<String>,
pub api_key: SecretString,
pub max_concurrent_analyses: usize,
pub max_analyse_count: usize,
pub max_tokens: u32,
pub max_retries: usize,
pub command: Option<String>,
pub args: Option<Vec<String>>,
}
}
api_keyis stored assecrecy::SecretStringand masked in debug output (env-only viaTOWL_LLM_API_KEY)providerselects the LLM backend:"claude","openai","claude-code", or"codex"commandandargsallow overriding the CLI binary path and arguments for CLI providers
| Field | Default |
|---|---|
provider | "claude" |
model | "claude-opus-4-8" |
base_url | None (provider default) |
max_concurrent_analyses | 5 |
max_analyse_count | 50 |
max_tokens | 4096 |
max_retries | 3 |
Environment Variable Overrides
| Variable | Overrides |
|---|---|
TOWL_LLM_API_KEY | – (env-only) |
TOWL_LLM_PROVIDER | llm.provider |
TOWL_LLM_MODEL | llm.model |
TOWL_LLM_BASE_URL | llm.base_url |
GitRepoInfo (internal)
#![allow(unused)]
fn main() {
pub(crate) struct GitRepoInfo {
pub owner: Owner,
pub repo: Repo,
}
}
from_path
#![allow(unused)]
fn main() {
pub(crate) async fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, TowlConfigError>
}
Internal function that discovers the git remote URL by running git remote get-url origin and parses the owner and repo name. Supports both HTTPS and SSH URL formats. Not part of the public API.
Errors:
GitRepoNotFound– Not inside a git repositoryGitRemoteNotFound– Nooriginremote configuredGitInvalidUrl– Could not parse owner/repo from the URL
Errors
#![allow(unused)]
fn main() {
pub enum TowlConfigError {
PathTraversalAttempt(PathBuf),
ConfigAlreadyExists(PathBuf),
WriteToFileError(PathBuf, std::io::Error),
UnableToParseToml(toml::ser::Error),
CouldNotCreateConfig(ConfigError),
GitRepoNotFound { message: String },
GitRemoteNotFound { message: String },
GitInvalidUrl { url: String, message: String },
TooManyConfigPatterns { field: String, count: usize, max_allowed: usize },
ConfigValueTooLong { field: String, length: usize, max_length: usize },
ContextLinesOutOfRange { value: usize, min: usize, max: usize },
}
}
Constants
| Constant | Value | Purpose |
|---|---|---|
DEFAULT_CONFIG_PATH | .towl.toml | Default config file name |
MAX_CONFIG_PATTERNS | 100 | Maximum entries per pattern array |
MAX_CONFIG_STRING_LENGTH | 512 | Maximum length for any single config string |
MIN_CONTEXT_LINES | 1 | Minimum include_context_lines value |
MAX_CONTEXT_LINES | 50 | Maximum include_context_lines value |