diff --git a/README.md b/README.md index 73b0069..3281435 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,10 @@ rag.bat # Interactive interface rag.bat index C:\my-project # Index your project first rag.bat search C:\my-project "query" # Fast search rag.bat explore C:\my-project # Interactive exploration + +# Direct Python entrypoint (after install): +rag-mini index C:\my-project +rag-mini search C:\my-project "query" ``` That's it. No external dependencies, no configuration required, no PhD in computer science needed. @@ -234,12 +238,12 @@ This implementation prioritizes: ## Documentation -- **[Quick Start Guide](docs/QUICK_START.md)** - Get running in 5 minutes +- **[Getting Started](docs/GETTING_STARTED.md)** - Get running in 5 minutes - **[Visual Diagrams](docs/DIAGRAMS.md)** - 📊 System flow charts and architecture diagrams - **[TUI Guide](docs/TUI_GUIDE.md)** - Complete walkthrough of the friendly interface - **[Technical Guide](docs/TECHNICAL_GUIDE.md)** - How the system actually works -- **[Configuration Guide](docs/CONFIGURATION.md)** - Customizing for your needs -- **[Development Guide](docs/DEVELOPMENT.md)** - Extending and modifying the code +- **[Troubleshooting](docs/TROUBLESHOOTING.md)** - Fix common issues +- **[Beginner Glossary](docs/BEGINNER_GLOSSARY.md)** - Friendly terms and concepts ## License diff --git a/assets/tts_onboarding.txt b/assets/tts_onboarding.txt new file mode 100644 index 0000000..8da7014 --- /dev/null +++ b/assets/tts_onboarding.txt @@ -0,0 +1,2 @@ +Welcome to FSS Mini RAG. This app makes your files searchable by meaning, not just keywords. On first launch, you’ll see three simple choices. Lite mode is the smallest download. It works great for search on any computer and is ready in minutes. Full offline mode adds a small local AI model so you can ask deeper questions without any internet. This is a larger download, but once it’s installed you’re fully offline. If you prefer cloud quality with a tiny download, choose the API option and paste your key from a provider like OpenAI. After you pick a mode, choose a folder, and click Index. That builds a private, local index on your machine. Then, ask a question like “Show me the authentication flow” or “Where do we write to the database?” You’ll get results with paths and line numbers, and you can ask follow-ups in Explore mode to get explanations with sources. Everything stays on your device unless you opt into a cloud provider. If you’re new, try the Demo button first to see it in action in under a minute. FSS Mini RAG—search smarter, learn faster, and stay in control of your data. + diff --git a/mini_rag/cli.py b/mini_rag/cli.py index cc4b353..47ebc55 100644 --- a/mini_rag/cli.py +++ b/mini_rag/cli.py @@ -135,9 +135,9 @@ def init(path: str, force: bool, reindex: bool, model: Optional[str]): # Show how to use console.print("\n[bold]Next steps:[/bold]") - console.print(" • Search your code: [cyan]mini-rag search \"your query\"[/cyan]") - console.print(" • Watch for changes: [cyan]mini-rag watch[/cyan]") - console.print(" • View statistics: [cyan]mini-rag stats[/cyan]\n") + console.print(" • Search your code: [cyan]rag-mini search \"your query\"[/cyan]") + console.print(" • Watch for changes: [cyan]rag-mini watch[/cyan]") + console.print(" • View statistics: [cyan]rag-mini stats[/cyan]\n") except Exception as e: console.print(f"\n[bold red]Error:[/bold red] {e}") @@ -166,7 +166,7 @@ def search(query: str, path: str, top_k: int, type: tuple, lang: tuple, show_con # Check if indexed rag_dir = project_path / '.mini-rag' if not rag_dir.exists(): - console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.") + console.print("[red]Error:[/red] Project not indexed. Run 'rag-mini init' first.") sys.exit(1) # Get performance monitor @@ -280,7 +280,7 @@ def stats(path: str): # Check if indexed rag_dir = project_path / '.mini-rag' if not rag_dir.exists(): - console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.") + console.print("[red]Error:[/red] Project not indexed. Run 'rag-mini init' first.") sys.exit(1) try: @@ -350,7 +350,7 @@ def debug_schema(path: str): rag_dir = project_path / '.mini-rag' if not rag_dir.exists(): - console.print("[red]No RAG index found. Run 'init' first.[/red]") + console.print("[red]No RAG index found. Run 'rag-mini init' first.[/red]") return # Connect to database @@ -418,7 +418,7 @@ def watch(path: str, delay: float, silent: bool): rag_dir = project_path / '.mini-rag' if not rag_dir.exists(): if not silent: - console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.") + console.print("[red]Error:[/red] Project not indexed. Run 'rag-mini init' first.") sys.exit(1) try: @@ -543,7 +543,7 @@ def update(path: str): # Check if indexed rag_dir = project_path / '.mini-rag' if not rag_dir.exists(): - console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.") + console.print("[red]Error:[/red] Project not indexed. Run 'rag-mini init' first.") sys.exit(1) try: @@ -598,7 +598,7 @@ def info(show_code: bool): console.print("\n[bold]Example Usage:[/bold]\n") code = """# Initialize a project -mini-rag init +rag-mini init # Search for code mini-rag search "database connection" @@ -609,10 +609,10 @@ mini-rag find-function connect_to_db mini-rag find-class UserModel # Watch for changes -mini-rag watch +rag-mini watch # Get statistics -mini-rag stats""" +rag-mini stats""" syntax = Syntax(code, "bash", theme="monokai") console.print(syntax) @@ -630,7 +630,7 @@ def server(path: str, port: int): # Check if indexed rag_dir = project_path / '.mini-rag' if not rag_dir.exists(): - console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.") + console.print("[red]Error:[/red] Project not indexed. Run 'rag-mini init' first.") sys.exit(1) try: @@ -692,7 +692,7 @@ def status(path: str, port: int, discovery: bool): console.print(f" • Error: {e}") else: console.print(" • Status: [red]❌ Not indexed[/red]") - console.print(" • Run 'rag-start' to initialize") + console.print(" • Run 'rag-mini init' to initialize") # Check server status console.print("\n[bold]🚀 Server Status:[/bold]") @@ -713,7 +713,7 @@ def status(path: str, port: int, discovery: bool): console.print(f" • [yellow]Server responding but with issues: {e}[/yellow]") else: console.print(f" • Status: [red]❌ Not running on port {port}[/red]") - console.print(" • Run 'rag-start' to start server") + console.print(" • Run 'rag-mini server' to start the server") # Run codebase discovery if requested if discovery and rag_dir.exists(): @@ -739,18 +739,18 @@ def status(path: str, port: int, discovery: bool): elif discovery and not rag_dir.exists(): console.print("\n[bold]🧠 Codebase Discovery:[/bold]") console.print(" [yellow]❌ Cannot run discovery - project not indexed[/yellow]") - console.print(" Run 'rag-start' first to initialize the system") + console.print(" Run 'rag-mini init' first to initialize the system") # Show next steps console.print("\n[bold]📋 Next Steps:[/bold]") if not rag_dir.exists(): - console.print(" 1. Run [cyan]rag-start[/cyan] to initialize and start RAG system") - console.print(" 2. Use [cyan]rag-search \"your query\"[/cyan] to search code") + console.print(" 1. Run [cyan]rag-mini init[/cyan] to initialize the RAG system") + console.print(" 2. Use [cyan]rag-mini search \"your query\"[/cyan] to search code") elif not client.is_running(): - console.print(" 1. Run [cyan]rag-start[/cyan] to start the server") - console.print(" 2. Use [cyan]rag-search \"your query\"[/cyan] to search code") + console.print(" 1. Run [cyan]rag-mini server[/cyan] to start the server") + console.print(" 2. Use [cyan]rag-mini search \"your query\"[/cyan] to search code") else: - console.print(" • System ready! Use [cyan]rag-search \"your query\"[/cyan] to search") + console.print(" • System ready! Use [cyan]rag-mini search \"your query\"[/cyan] to search") console.print(" • Add [cyan]--discovery[/cyan] flag to run intelligent codebase analysis") console.print() diff --git a/mini_rag/ollama_embeddings.py b/mini_rag/ollama_embeddings.py index 43fada9..c546e74 100644 --- a/mini_rag/ollama_embeddings.py +++ b/mini_rag/ollama_embeddings.py @@ -472,27 +472,27 @@ class OllamaEmbedder: def get_embedding_info(self) -> Dict[str, str]: """Get human-readable embedding system information for installer.""" status = self.get_status() - - if status["mode"] == "ollama": + mode = status.get("mode", "unknown") + if mode == "ollama": return { "method": f"Ollama ({status['ollama_model']})", "status": "working" } - elif status["mode"] == "ml": + # Treat legacy/alternate naming uniformly + if mode in ("fallback", "ml"): return { "method": f"ML Fallback ({status['fallback_model']})", "status": "working" } - elif status["mode"] == "hash": + if mode == "hash": return { "method": "Hash-based (basic similarity)", "status": "working" } - else: - return { - "method": "Unknown", - "status": "error" - } + return { + "method": "Unknown", + "status": "error" + } def warmup(self): """Warm up the embedding system with a dummy request.""" diff --git a/mini_rag/server.py b/mini_rag/server.py index 3d43e0a..c06aa8d 100644 --- a/mini_rag/server.py +++ b/mini_rag/server.py @@ -272,7 +272,7 @@ class RAGClient: except ConnectionRefusedError: return { 'success': False, - 'error': 'RAG server not running. Start with: mini-rag server' + 'error': 'RAG server not running. Start with: rag-mini server' } except ConnectionError as e: # Try legacy mode without message framing diff --git a/rag-tui.py b/rag-tui.py index 41fcdb3..0ab14e0 100755 --- a/rag-tui.py +++ b/rag-tui.py @@ -182,13 +182,15 @@ class SimpleTUI: "Keep current project (go back to main menu)", "Use current directory (this folder)", "Enter different project path", - "Browse recent projects" + "Browse recent projects", + "Open folder picker (GUI)" ] else: options = [ "Use current directory (perfect for beginners - try the RAG codebase!)", "Enter project path (if you have a specific project)", - "Browse recent projects" + "Browse recent projects", + "Open folder picker (GUI)" ] choice = self.show_menu("Choose project directory", options, show_cli=False, back_option="Back to main menu") @@ -212,6 +214,12 @@ class SimpleTUI: elif choice == 3: # Browse recent projects self.browse_recent_projects() + elif choice == 4: + picked = self._pick_folder_dialog() + if picked: + self.project_path = Path(picked) + print(f"✅ Selected: {self.project_path}") + self._save_last_project() else: if choice == 0: # Use current directory @@ -224,6 +232,12 @@ class SimpleTUI: elif choice == 2: # Browse recent projects self.browse_recent_projects() + elif choice == 3: + picked = self._pick_folder_dialog() + if picked: + self.project_path = Path(picked) + print(f"✅ Selected: {self.project_path}") + self._save_last_project() input("\nPress Enter to continue...") @@ -502,6 +516,23 @@ class SimpleTUI: print() input("Press Enter to continue...") + + def _pick_folder_dialog(self) -> Optional[str]: + """Open a minimal cross-platform folder picker dialog and return path or None.""" + try: + import tkinter as tk + from tkinter import filedialog + root = tk.Tk() + root.withdraw() + root.update() + directory = filedialog.askdirectory(title="Select project folder to index") + root.destroy() + if directory and Path(directory).exists(): + return directory + return None + except Exception: + print("❌ Folder picker not available on this system") + return None def _show_existing_index_info(self, rag_dir: Path) -> bool: """Show essential info about existing index and ask about re-indexing.""" @@ -1309,18 +1340,18 @@ Your suggested question (under 10 words):""" from mini_rag.ollama_embeddings import OllamaEmbedder embedder = OllamaEmbedder() - info = embedder.get_status() + status = embedder.get_status() print("🧠 Embedding System:") - method = info.get('method', 'unknown') - if method == 'ollama': + mode = status.get('mode', 'unknown') + if mode == 'ollama': print(" ✅ Ollama (high quality)") - elif method == 'ml': + elif mode == 'fallback': print(" ✅ ML fallback (good quality)") - elif method == 'hash': + elif mode == 'hash': print(" ⚠️ Hash fallback (basic quality)") else: - print(f" ❓ Unknown: {method}") + print(f" ❓ Unknown: {mode}") except Exception as e: print(f"🧠 Embedding System: ❌ Error: {e}") diff --git a/tests/02_search_examples.py b/tests/02_search_examples.py index 271c1ab..1708934 100644 --- a/tests/02_search_examples.py +++ b/tests/02_search_examples.py @@ -124,7 +124,7 @@ def main(): project_path = Path(__file__).parent if not (project_path / '.mini-rag').exists(): - console.print("[red]Error: No RAG index found. Run 'mini-rag index' first.[/red]") + console.print("[red]Error: No RAG index found. Run 'rag-mini index' first.[/red]") console.print(f"[dim]Looked in: {project_path / '.mini-rag'}[/dim]") return diff --git a/tests/test_hybrid_search.py b/tests/test_hybrid_search.py index c3c526a..4b728e4 100644 --- a/tests/test_hybrid_search.py +++ b/tests/test_hybrid_search.py @@ -328,7 +328,7 @@ def main(): project_path = Path.cwd() if not (project_path / '.mini-rag').exists(): - console.print("[red]Error: No RAG index found. Run 'mini-rag index' first.[/red]") + console.print("[red]Error: No RAG index found. Run 'rag-mini index' first.[/red]") return # Create tester