This commit is contained in:
BobAi 2025-08-15 14:08:15 +10:00
commit 1e9eb9bc1a
8 changed files with 80 additions and 43 deletions

View File

@ -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

View File

@ -0,0 +1,2 @@
Welcome to FSS Mini RAG. This app makes your files searchable by meaning, not just keywords. On first launch, youll 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 its installed youre 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?” Youll 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 youre 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.

View File

@ -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()

View File

@ -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."""

View File

@ -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

View File

@ -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...")
@ -503,6 +517,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."""
print("📊 EXISTING INDEX FOUND")
@ -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}")

View File

@ -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

View File

@ -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