Release v1.5.0

- **Multi-provider support** — `Provider` trait (`src/provider/traits.rs`) abstracts over different AI providers; `AnthropicProvider` uses the native Anthropic API, `OpenAiProvider` (`src/provider/openai.rs`) covers OpenAI, DeepSeek, Ollama, LM Studio, and any `/v1/chat/completions` endpoint
- **Provider registry** — `ProviderRegistry` (`src/provider/registry.rs`) lazily builds only the providers referenced by the active profile; resolves role bindings to `(provider, model)` pairs
- **Profiles** — `[profiles.<name>]` config sections bind four roles (`simple`, `planner`, `executor`, `patcher`) to provider/model pairs; `General.active_profile` selects the active profile
- **Routing classifier** — `classify_complexity()` (`src/provider/routing.rs`) routes prompts as `Simple` (single-turn) or `Complex` (agent loop) using heuristic word count + keyword matching, with `hybrid` and `classifier_api` strategies
- **Agent loop** — `run_agent_loop()` (`src/provider/agent_loop.rs`) for complex prompts: planner step (produces a numbered plan), plan approval dialog (`[Enter]` approve / `[e]` edit / `[Esc]` cancel), executor loop with tool dispatch
- **Prompt templates** — `PLANNER_PREFIX` and `EXECUTOR_PREFIX` (`src/provider/prompts.rs`) prepended to system prompt for planner and executor roles
- **`ait profile list`** — prints all configured profiles with their role bindings; active profile marked with `*`
- **`ait profile use <name>`** — validates a profile exists (runtime switching via REPL planned)
- **Active profile in REPL prompt** — non-default profiles shown as `ait [profile] ~/path> `
- **`profile` and `model` fields on `Message`** — recorded on assistant messages in session JSON
- **`[routing]` config section** — `strategy` (`heuristic` / `classifier_api` / `hybrid`), `[routing.heuristic]` with `complex_word_threshold` and `complex_keywords`
- **Credential store integration** — API keys are resolved from the system credential store (macOS Keychain, Linux secret-service, Windows Credential Manager) first, falling back to environment variables
- **`ait auth set <provider>`** — store an API key securely with validation (lists models to verify the key works)
- **`ait auth list`** — show which providers have keys stored (credential store + env vars)
- **`ait auth remove <provider>`** — remove a stored key
- **`ait model list [--provider <name>]`** — list available models from configured providers
- **Agent loop: planner reads files before planning** — planner gets read-only tools (`read_file`, `list_files`, `grep_files`, `cwd`) with no 5KB truncation; gathers context before producing the plan
- **Agent loop: file diff status** — `Creating file diff for <path>...` shown while computing diffs in `write_file`/`patch_file` (replaces blank screen after spinner disappears)
- **Agent loop: wrap-up with context** — when hitting the turn limit, the model receives the original task, plan, and list of modified files to produce an accurate summary instead of hallucinating
- **Agent loop: consecutive error detection** — 3 consecutive tool errors break the loop to avoid infinite retries (e.g. repeated `patch_file` failures)
- **`AIT_NO_CREDENTIAL_STORE`** env var — disables credential store lookups for CI/Docker/test environments

- Agent loop executor limit increased from 30 to 100 iterations
- Agent loop wrap-up fires 2 turns before the limit (with empty tools to force prose) instead of on the last turn
- Executor gets a clean session (original prompt + plan only) — no planner tool history, avoids cross-provider tool ID format mismatches
- Planner prompt updated: "gather context efficiently in 2-3 tool turns, batch calls, use grep first"
- Planner budget hint fires at turn 3 to stop context gathering and produce the plan
- Config reload now also checks right before sending AI prompts (not just at REPL loop top)
- Ctrl+C now works during proactive rate limit waits
- Rate limit countdown display fixed (explicit `write_all` + `flush` per tick)
- Terminal line cleared on Ctrl+C to prevent spinner remnants
- Fixed UTF-8 panic in OpenAI debug log truncation (multi-byte chars like `─` and `⠹`)

- `Config.providers` is now `HashMap<String, ProviderConfig>` (was a single-field `Providers` struct) — supports any number of named providers
- `AiContext` uses `ProviderRegistry` instead of direct `AnthropicProvider`; model is resolved per-request from the active profile
- `handle_prompt` uses the routing classifier to dispatch simple prompts to the single-turn loop and complex prompts to the agent loop
- Default config template updated with `[profiles.default]`, `[routing]`, and multi-provider `[providers.*]` sections
- `ait config validate` now checks all configured providers and validates the active profile exists

- `AnthropicProvider::complete()` and `stream()` — dead code; streaming will be rewritten for TUI in v2
- `AnthropicProvider::from_config()` — superseded by `new()` used by the registry
- `Provider::name()` trait method — unused

- Added `async-trait` 0.1 (Provider trait)
- Added `keyring` 3.x (system credential store: macOS Keychain, Linux secret-service)
- Added `rpassword` 5.x (hidden password input for `ait auth set`)