feat(phase5): implement mode consolidation and tool availability system

Implements Phase 5 from the roadmap with complete mode-based tool filtering:

- Add Mode enum (Chat/Code) with FromStr trait implementation
- Extend Config with ModeConfig for per-mode tool availability
- Update ToolRegistry to enforce mode-based filtering
- Add --code/-c CLI argument to start in code mode
- Implement TUI commands: :mode, :code, :chat, :tools
- Add operating mode indicator to status line (💬/💻 badges)
- Create comprehensive documentation in docs/phase5-mode-system.md

Default configuration:
- Chat mode: only web_search allowed
- Code mode: all tools allowed (wildcard *)

All code compiles cleanly with cargo clippy passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-09 20:17:41 +02:00
parent 33d11ae223
commit e57844e742
9 changed files with 581 additions and 7 deletions

View File

@@ -1,7 +1,8 @@
//! OWLEN CLI - Chat TUI client
use anyhow::Result;
use owlen_core::{session::SessionController, storage::StorageManager};
use clap::Parser;
use owlen_core::{mode::Mode, session::SessionController, storage::StorageManager};
use owlen_ollama::OllamaProvider;
use owlen_tui::tui_controller::{TuiController, TuiRequest};
use owlen_tui::{config, ui, AppState, ChatApp, Event, EventHandler, SessionEvent};
@@ -17,11 +18,22 @@ use crossterm::{
};
use ratatui::{prelude::CrosstermBackend, Terminal};
/// Owlen - Terminal UI for LLM chat
#[derive(Parser, Debug)]
#[command(name = "owlen")]
#[command(about = "Terminal UI for LLM chat with Ollama", long_about = None)]
struct Args {
/// Start in code mode (enables all tools)
#[arg(long, short = 'c')]
code: bool,
}
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> {
// (imports completed above)
// Parse command-line arguments
let args = Args::parse();
let initial_mode = if args.code { Mode::Code } else { Mode::Chat };
// (main logic starts below)
// Set auto-consent for TUI mode to prevent blocking stdin reads
std::env::set_var("OWLEN_AUTO_CONSENT", "1");
@@ -53,6 +65,9 @@ async fn main() -> Result<()> {
let (mut app, mut session_rx) = ChatApp::new(controller).await?;
app.initialize_models().await?;
// Set the initial mode
app.set_mode(initial_mode).await;
// Event infrastructure
let cancellation_token = CancellationToken::new();
let (event_tx, event_rx) = mpsc::unbounded_channel();