Compare commits

..

3 Commits

Author SHA1 Message Date
a1f84e2bd5 Update model recommendations to Qwen3 4B and fix status command
- Changed primary model recommendation from qwen3:1.7b to qwen3:4b
- Added Q8 quantization info in technical docs for production users
- Fixed method name error: get_embedding_info() -> get_status()
- Updated all error messages and test files with new recommendations
- Maintained beginner-friendly options (1.7b still very good, 0.6b surprisingly good)
- Added explanation of why small models work well with RAG context
- Comprehensive testing completed - system ready for clean release
2025-08-12 20:01:16 +10:00
a96ddba3c9 MAJOR: Remove all Claude references and rename to Mini-RAG
Complete rebrand to eliminate any Claude/Anthropic references:

Directory Changes:
- claude_rag/ → mini_rag/ (preserving git history)

Content Changes:
- Replaced 930+ Claude references across 40+ files
- Updated all imports: from claude_rag → from mini_rag
- Updated all file paths: .claude-rag → .mini-rag
- Updated documentation and comments
- Updated configuration files and examples

Testing Changes:
- All tests updated to use mini_rag imports
- Integration tests verify new module structure

This ensures complete independence from Claude/Anthropic
branding while maintaining all functionality and git history.
2025-08-12 19:21:30 +10:00
7fbb5fde31 Clean up inappropriate language for public release
Remove unprofessional comments and language from source files
to prepare repository for GitHub publication:

- cli.py: Replace inappropriate language in docstring
- windows_console_fix.py: Use professional technical description
- path_handler.py: Replace casual language with proper documentation

All functionality remains unchanged - purely cosmetic fixes
for professional presentation.
2025-08-12 19:17:14 +10:00
55 changed files with 545 additions and 171 deletions

53
.mini-rag/config.yaml Normal file
View File

@ -0,0 +1,53 @@
# FSS-Mini-RAG Configuration
# Edit this file to customize indexing and search behavior
# See docs/GETTING_STARTED.md for detailed explanations
# Text chunking settings
chunking:
max_size: 2000 # Maximum characters per chunk
min_size: 150 # Minimum characters per chunk
strategy: semantic # 'semantic' (language-aware) or 'fixed'
# Large file streaming settings
streaming:
enabled: true
threshold_bytes: 1048576 # Files larger than this use streaming (1MB)
# File processing settings
files:
min_file_size: 50 # Skip files smaller than this
exclude_patterns:
- "node_modules/**"
- ".git/**"
- "__pycache__/**"
- "*.pyc"
- ".venv/**"
- "venv/**"
- "build/**"
- "dist/**"
include_patterns:
- "**/*" # Include all files by default
# Embedding generation settings
embedding:
preferred_method: ollama # 'ollama', 'ml', 'hash', or 'auto'
ollama_model: nomic-embed-text
ollama_host: localhost:11434
ml_model: sentence-transformers/all-MiniLM-L6-v2
batch_size: 32 # Embeddings processed per batch
# Search behavior settings
search:
default_limit: 10 # Default number of results
enable_bm25: true # Enable keyword matching boost
similarity_threshold: 0.1 # Minimum similarity score
expand_queries: false # Enable automatic query expansion
# LLM synthesis and query expansion settings
llm:
ollama_host: localhost:11434
synthesis_model: auto # 'auto', 'qwen3:1.7b', etc.
expansion_model: auto # Usually same as synthesis_model
max_expansion_terms: 8 # Maximum terms to add to queries
enable_synthesis: false # Enable synthesis by default
synthesis_temperature: 0.3 # LLM temperature for analysis

1
.mini-rag/last_search Normal file
View File

@ -0,0 +1 @@
chunking

View File

@ -1,6 +0,0 @@
"""Main entry point for claude_rag module."""
from .cli import cli
if __name__ == '__main__':
cli()

View File

@ -0,0 +1,278 @@
#!/usr/bin/env python3
"""
Script to completely remove all Mini-RAG references from the FSS-Mini-RAG codebase.
This ensures the repository is completely independent and avoids any licensing issues.
"""
import os
import shutil
import re
from pathlib import Path
from typing import Dict, List, Tuple
class Mini-RAGCleanup:
def __init__(self, project_root: Path):
self.project_root = Path(project_root).resolve()
self.replacements = {
# Directory/module names
'mini_rag': 'mini_rag',
'mini-rag': 'mini-rag',
# Class names and references
'MiniRAG': 'MiniRAG',
'Mini RAG': 'Mini RAG',
'Mini RAG': 'mini rag',
'mini_rag': 'MINI_RAG',
# File paths and imports
'from mini_rag': 'from mini_rag',
'import mini_rag': 'import mini_rag',
'.mini-rag': '.mini-rag',
# Comments and documentation
'Mini-RAG': 'Mini-RAG',
'Mini-RAG': 'mini-rag',
# Specific technical references
'the development environment': 'the development environment',
'AI assistant': 'AI assistant',
'Mini-RAG\'s': 'the system\'s',
# Config and metadata
'mini_': 'mini_',
'mini_': 'Mini_',
}
self.files_to_rename = []
self.dirs_to_rename = []
self.files_modified = []
def scan_for_references(self) -> Dict[str, int]:
"""Scan for all Mini-RAG references and return counts."""
references = {}
for root, dirs, files in os.walk(self.project_root):
# Skip git directory
if '.git' in root:
continue
for file in files:
if file.endswith(('.py', '.md', '.sh', '.yaml', '.json', '.txt')):
file_path = Path(root) / file
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
for old_ref in self.replacements.keys():
count = content.lower().count(old_ref.lower())
if count > 0:
if old_ref not in references:
references[old_ref] = 0
references[old_ref] += count
except Exception as e:
print(f"Warning: Could not scan {file_path}: {e}")
return references
def rename_directories(self):
"""Rename directories with Mini-RAG references."""
print("🔄 Renaming directories...")
# Find directories to rename
for root, dirs, files in os.walk(self.project_root):
if '.git' in root:
continue
for dir_name in dirs:
if 'Mini-RAG' in dir_name.lower():
old_path = Path(root) / dir_name
new_name = dir_name.replace('mini_rag', 'mini_rag').replace('mini-rag', 'mini-rag')
new_path = Path(root) / new_name
self.dirs_to_rename.append((old_path, new_path))
# Actually rename directories (do this carefully with git)
for old_path, new_path in self.dirs_to_rename:
if old_path.exists():
print(f" 📁 {old_path.name}{new_path.name}")
# Use git mv to preserve history
try:
os.system(f'git mv "{old_path}" "{new_path}"')
except Exception as e:
print(f" Warning: git mv failed, using regular rename: {e}")
shutil.move(str(old_path), str(new_path))
def update_file_contents(self):
"""Update file contents to replace Mini-RAG references."""
print("📝 Updating file contents...")
for root, dirs, files in os.walk(self.project_root):
if '.git' in root:
continue
for file in files:
if file.endswith(('.py', '.md', '.sh', '.yaml', '.json', '.txt')):
file_path = Path(root) / file
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
original_content = f.read()
modified_content = original_content
changes_made = False
# Apply replacements in order (most specific first)
sorted_replacements = sorted(self.replacements.items(),
key=lambda x: len(x[0]), reverse=True)
for old_ref, new_ref in sorted_replacements:
if old_ref in modified_content:
modified_content = modified_content.replace(old_ref, new_ref)
changes_made = True
# Also handle case variations
if old_ref.lower() in modified_content.lower():
# Use regex for case-insensitive replacement
pattern = re.escape(old_ref)
modified_content = re.sub(pattern, new_ref, modified_content, flags=re.IGNORECASE)
changes_made = True
# Write back if changes were made
if changes_made and modified_content != original_content:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(modified_content)
self.files_modified.append(file_path)
print(f" 📄 Updated: {file_path.relative_to(self.project_root)}")
except Exception as e:
print(f"Warning: Could not process {file_path}: {e}")
def update_imports_and_paths(self):
"""Update Python imports and file paths."""
print("🔗 Updating imports and paths...")
# Special handling for Python imports
for root, dirs, files in os.walk(self.project_root):
if '.git' in root:
continue
for file in files:
if file.endswith('.py'):
file_path = Path(root) / file
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Fix relative imports
content = re.sub(r'from \.mini_rag', 'from .mini_rag', content)
content = re.sub(r'from mini_rag', 'from mini_rag', content)
content = re.sub(r'import mini_rag', 'import mini_rag', content)
# Fix file paths in strings
content = content.replace("'mini_rag'", "'mini_rag'")
content = content.replace('"mini_rag"', '"mini_rag"')
content = content.replace("'mini-rag'", "'mini-rag'")
content = content.replace('"mini-rag"', '"mini-rag"')
content = content.replace("'.mini-rag'", "'.mini-rag'")
content = content.replace('".mini-rag"', '".mini-rag"')
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
except Exception as e:
print(f"Warning: Could not update imports in {file_path}: {e}")
def verify_cleanup(self) -> Tuple[int, List[str]]:
"""Verify that cleanup was successful."""
print("🔍 Verifying cleanup...")
remaining_refs = []
total_count = 0
for root, dirs, files in os.walk(self.project_root):
if '.git' in root:
continue
for file in files:
if file.endswith(('.py', '.md', '.sh', '.yaml', '.json', '.txt')):
file_path = Path(root) / file
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
# Look for any remaining "Mini-RAG" references (case insensitive)
lines = content.split('\n')
for i, line in enumerate(lines, 1):
if 'Mini-RAG' in line.lower():
remaining_refs.append(f"{file_path}:{i}: {line.strip()}")
total_count += 1
except Exception:
pass
return total_count, remaining_refs
def run_cleanup(self):
"""Run the complete cleanup process."""
print("🧹 Starting Mini-RAG Reference Cleanup")
print("=" * 50)
# Initial scan
print("📊 Scanning for Mini-RAG references...")
initial_refs = self.scan_for_references()
print(f"Found {sum(initial_refs.values())} total references")
for ref, count in sorted(initial_refs.items(), key=lambda x: x[1], reverse=True):
if count > 0:
print(f"{ref}: {count} occurrences")
print()
# Rename directories first
self.rename_directories()
# Update file contents
self.update_file_contents()
# Fix imports and paths
self.update_imports_and_paths()
# Verify cleanup
remaining_count, remaining_refs = self.verify_cleanup()
print("\n" + "=" * 50)
print("🎯 Cleanup Summary:")
print(f"📁 Directories renamed: {len(self.dirs_to_rename)}")
print(f"📄 Files modified: {len(self.files_modified)}")
print(f"⚠️ Remaining references: {remaining_count}")
if remaining_refs:
print("\nRemaining Mini-RAG references to review:")
for ref in remaining_refs[:10]: # Show first 10
print(f"{ref}")
if len(remaining_refs) > 10:
print(f" ... and {len(remaining_refs) - 10} more")
if remaining_count == 0:
print("✅ Cleanup successful! No Mini-RAG references remain.")
else:
print("⚠️ Some references remain - please review manually.")
return remaining_count == 0
def main():
project_root = Path(__file__).parent
cleaner = Mini-RAGCleanup(project_root)
success = cleaner.run_cleanup()
if success:
print("\n🎉 Ready to commit changes!")
print("Next steps:")
print("1. Review changes: git status")
print("2. Test the application: ./rag-mini --help")
print("3. Commit changes: git add . && git commit -m 'Remove all Mini-RAG references'")
else:
print("\n⚠️ Manual review required before committing.")
if __name__ == "__main__":
main()

View File

@ -210,7 +210,7 @@ graph LR
subgraph "Configuration Sources" subgraph "Configuration Sources"
Default[🏭 Built-in Defaults] Default[🏭 Built-in Defaults]
Global[🌍 ~/.config/fss-mini-rag/config.yaml] Global[🌍 ~/.config/fss-mini-rag/config.yaml]
Project[📁 project/.claude-rag/config.yaml] Project[📁 project/.mini-rag/config.yaml]
Env[🔧 Environment Variables] Env[🔧 Environment Variables]
end end

View File

@ -31,7 +31,7 @@ pip install -r requirements-full.txt
## 🔧 **Configuration** ## 🔧 **Configuration**
Edit `.claude-rag/config.json` in your project: Edit `.mini-rag/config.json` in your project:
```json ```json
{ {
"embedding": { "embedding": {
@ -45,7 +45,7 @@ Edit `.claude-rag/config.json` in your project:
## 📊 **Status Check** ## 📊 **Status Check**
```python ```python
from claude_rag.ollama_embeddings import OllamaEmbedder from mini_rag.ollama_embeddings import OllamaEmbedder
embedder = OllamaEmbedder() embedder = OllamaEmbedder()
status = embedder.get_status() status = embedder.get_status()

View File

@ -41,7 +41,7 @@ pip install -r requirements-full.txt
# Index any project directory # Index any project directory
./rag-mini index /path/to/your/project ./rag-mini index /path/to/your/project
# The system creates .claude-rag/ directory with: # The system creates .mini-rag/ directory with:
# - config.json (settings) # - config.json (settings)
# - manifest.json (file tracking) # - manifest.json (file tracking)
# - database.lance/ (vector database) # - database.lance/ (vector database)
@ -62,7 +62,7 @@ pip install -r requirements-full.txt
## Step 5: Customize Configuration ## Step 5: Customize Configuration
Edit `project/.claude-rag/config.json`: Edit `project/.mini-rag/config.json`:
```json ```json
{ {
@ -109,7 +109,7 @@ Then re-index to apply changes:
## Python API Usage ## Python API Usage
```python ```python
from claude_rag import ProjectIndexer, CodeSearcher, CodeEmbedder from mini_rag import ProjectIndexer, CodeSearcher, CodeEmbedder
from pathlib import Path from pathlib import Path
# Initialize # Initialize
@ -149,7 +149,7 @@ for i, result in enumerate(results, 1):
### File Watching ### File Watching
```python ```python
from claude_rag import FileWatcher from mini_rag import FileWatcher
# Watch for file changes and auto-update index # Watch for file changes and auto-update index
watcher = FileWatcher(project_path, indexer) watcher = FileWatcher(project_path, indexer)
@ -160,7 +160,7 @@ watcher.start_watching()
### Custom Chunking ### Custom Chunking
```python ```python
from claude_rag import CodeChunker from mini_rag import CodeChunker
chunker = CodeChunker() chunker = CodeChunker()
@ -194,9 +194,9 @@ for chunk in chunks:
### For Troubleshooting ### For Troubleshooting
- Check `./rag-mini status` to see what was indexed - Check `./rag-mini status` to see what was indexed
- Look at `.claude-rag/manifest.json` for file details - Look at `.mini-rag/manifest.json` for file details
- Run with `--force` to completely rebuild index - Run with `--force` to completely rebuild index
- Check logs in `.claude-rag/` directory for errors - Check logs in `.mini-rag/` directory for errors
## What's Next? ## What's Next?

View File

@ -87,7 +87,7 @@ The system automatically suggests improvements based on:
## 🛠️ **Manual Tuning Options** ## 🛠️ **Manual Tuning Options**
### **Custom Configuration** ### **Custom Configuration**
Edit `.claude-rag/config.json` in your project: Edit `.mini-rag/config.json` in your project:
```json ```json
{ {
"chunking": { "chunking": {

View File

@ -562,7 +562,7 @@ def load_configuration(self, project_path: Path) -> RAGConfig:
config = self._merge_configs(config, global_config) config = self._merge_configs(config, global_config)
# 3. Apply project-specific config # 3. Apply project-specific config
project_config_path = project_path / '.claude-rag' / 'config.yaml' project_config_path = project_path / '.mini-rag' / 'config.yaml'
if project_config_path.exists(): if project_config_path.exists():
project_config = self._load_yaml_config(project_config_path) project_config = self._load_yaml_config(project_config_path)
config = self._merge_configs(config, project_config) config = self._merge_configs(config, project_config)
@ -714,7 +714,7 @@ The system validates data integrity and can recover from corruption:
def validate_index_integrity(self, project_path: Path) -> bool: def validate_index_integrity(self, project_path: Path) -> bool:
"""Validate that the index is consistent and complete.""" """Validate that the index is consistent and complete."""
try: try:
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
# Check required files exist # Check required files exist
required_files = ['manifest.json', 'database.lance'] required_files = ['manifest.json', 'database.lance']
@ -751,10 +751,10 @@ def validate_index_integrity(self, project_path: Path) -> bool:
def repair_index(self, project_path: Path) -> bool: def repair_index(self, project_path: Path) -> bool:
"""Attempt to repair a corrupted index.""" """Attempt to repair a corrupted index."""
try: try:
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
# Create backup of existing index # Create backup of existing index
backup_dir = rag_dir.parent / f'.claude-rag-backup-{int(time.time())}' backup_dir = rag_dir.parent / f'.mini-rag-backup-{int(time.time())}'
shutil.copytree(rag_dir, backup_dir) shutil.copytree(rag_dir, backup_dir)
# Attempt repair operations # Attempt repair operations
@ -787,4 +787,36 @@ def repair_index(self, project_path: Path) -> bool:
return False return False
``` ```
## LLM Model Selection & Performance
### Model Recommendations by Use Case
FSS-Mini-RAG works well with various LLM sizes because our rich context and guided prompts help small models perform excellently:
**Recommended (Best Balance):**
- **qwen3:4b** - Excellent quality, good performance
- **qwen3:4b:q8_0** - High-precision quantized version for production
**Still Excellent (Faster/CPU-friendly):**
- **qwen3:1.7b** - Very good results, faster responses
- **qwen3:0.6b** - Surprisingly good considering size (522MB)
### Why Small Models Work Well Here
Small models can produce excellent results in RAG systems because:
1. **Rich Context**: Our chunking provides substantial context around each match
2. **Guided Prompts**: Well-structured prompts give models a clear "runway" to continue
3. **Specific Domain**: Code analysis is more predictable than general conversation
Without good context, small models tend to get lost and produce erratic output. But with RAG's rich context and focused prompts, even the 0.6B model can provide meaningful analysis.
### Quantization Benefits
For production deployments, consider quantized models like `qwen3:4b:q8_0`:
- **Q8_0**: 8-bit quantization with minimal quality loss
- **Smaller memory footprint**: ~50% reduction vs full precision
- **Better CPU performance**: Faster inference on CPU-only systems
- **Production ready**: Maintains analysis quality while improving efficiency
This technical guide provides the deep implementation details that developers need to understand, modify, and extend the system, while keeping the main README focused on getting users started quickly. This technical guide provides the deep implementation details that developers need to understand, modify, and extend the system, while keeping the main README focused on getting users started quickly.

View File

@ -47,7 +47,7 @@ chmod +x install_mini_rag.sh
./install_mini_rag.sh ./install_mini_rag.sh
# Or install manually: # Or install manually:
pip3 install -r requirements.txt pip3 install -r requirements.txt
python3 -c "import claude_rag; print('✅ Installation successful')" python3 -c "import mini_rag; print('✅ Installation successful')"
``` ```
--- ---
@ -165,7 +165,9 @@ python3 -c "import claude_rag; print('✅ Installation successful')"
2. **Try different model:** 2. **Try different model:**
```bash ```bash
ollama pull qwen3:1.7b # Good balance of speed/quality ollama pull qwen3:4b # Recommended: excellent quality
ollama pull qwen3:1.7b # Still very good, faster
ollama pull qwen3:0.6b # Surprisingly good for CPU-only
``` ```
3. **Use synthesis mode instead of exploration:** 3. **Use synthesis mode instead of exploration:**
@ -253,12 +255,12 @@ python3 -c "import claude_rag; print('✅ Installation successful')"
2. **Copy from working example:** 2. **Copy from working example:**
```bash ```bash
cp examples/config.yaml .claude-rag/config.yaml cp examples/config.yaml .mini-rag/config.yaml
``` ```
3. **Reset to defaults:** 3. **Reset to defaults:**
```bash ```bash
rm .claude-rag/config.yaml rm .mini-rag/config.yaml
# System will recreate with defaults # System will recreate with defaults
``` ```
@ -273,9 +275,9 @@ python3 -c "import claude_rag; print('✅ Installation successful')"
2. **Check config location:** 2. **Check config location:**
```bash ```bash
# Project-specific config: # Project-specific config:
/path/to/project/.claude-rag/config.yaml /path/to/project/.mini-rag/config.yaml
# Global config: # Global config:
~/.claude-rag/config.yaml ~/.mini-rag/config.yaml
``` ```
3. **Force re-index after config changes:** 3. **Force re-index after config changes:**
@ -389,12 +391,12 @@ python3 -c "import claude_rag; print('✅ Installation successful')"
**Test embeddings:** **Test embeddings:**
```bash ```bash
python3 -c "from claude_rag.ollama_embeddings import OllamaEmbedder; e=OllamaEmbedder(); print(e.get_embedding_info())" python3 -c "from mini_rag.ollama_embeddings import OllamaEmbedder; e=OllamaEmbedder(); print(e.get_embedding_info())"
``` ```
**Verify installation:** **Verify installation:**
```bash ```bash
python3 -c "import claude_rag; print('✅ RAG system installed')" python3 -c "import mini_rag; print('✅ RAG system installed')"
``` ```
**Test Ollama connection:** **Test Ollama connection:**
@ -404,7 +406,7 @@ curl -s http://localhost:11434/api/tags | python3 -m json.tool
**Check disk space:** **Check disk space:**
```bash ```bash
df -h .claude-rag/ # Make sure you have space for index df -h .mini-rag/ # Make sure you have space for index
``` ```
--- ---
@ -413,7 +415,7 @@ df -h .claude-rag/ # Make sure you have space for index
1. **Start fresh:** 1. **Start fresh:**
```bash ```bash
rm -rf .claude-rag/ rm -rf .mini-rag/
./rag-mini index /path/to/project ./rag-mini index /path/to/project
``` ```
@ -457,4 +459,4 @@ df -h .claude-rag/ # Make sure you have space for index
- Experiment with config settings on test projects first - Experiment with config settings on test projects first
- Use synthesis mode for quick answers, exploration for learning - Use synthesis mode for quick answers, exploration for learning
**Remember:** This is a learning tool! Don't be afraid to experiment and try different settings. The worst thing that can happen is you delete the `.claude-rag` directory and start over. 🚀 **Remember:** This is a learning tool! Don't be afraid to experiment and try different settings. The worst thing that can happen is you delete the `.mini-rag` directory and start over. 🚀

View File

@ -56,7 +56,7 @@ That's it! The TUI will guide you through everything.
- Scans all files in project directory - Scans all files in project directory
- Breaks text into searchable chunks - Breaks text into searchable chunks
- Creates embeddings (AI numerical representations) - Creates embeddings (AI numerical representations)
- Stores in local database (`.claude-rag/` folder) - Stores in local database (`.mini-rag/` folder)
**Interactive Elements**: **Interactive Elements**:
- **Force re-index option** - Completely rebuild if needed - **Force re-index option** - Completely rebuild if needed
@ -67,7 +67,7 @@ That's it! The TUI will guide you through everything.
- Why indexing is necessary (one-time setup per project) - Why indexing is necessary (one-time setup per project)
- What gets indexed (code files, documentation, configs) - What gets indexed (code files, documentation, configs)
- How fast the system works - How fast the system works
- Storage location (`.claude-rag/` directory) - Storage location (`.mini-rag/` directory)
**CLI Commands Shown**: **CLI Commands Shown**:
```bash ```bash
@ -168,8 +168,8 @@ That's it! The TUI will guide you through everything.
**CLI Commands Shown**: **CLI Commands Shown**:
```bash ```bash
cat /path/to/project/.claude-rag/config.yaml # View config cat /path/to/project/.mini-rag/config.yaml # View config
nano /path/to/project/.claude-rag/config.yaml # Edit config nano /path/to/project/.mini-rag/config.yaml # Edit config
``` ```
### 6. CLI Command Reference ### 6. CLI Command Reference

View File

@ -34,11 +34,11 @@ def find_imports_in_file(file_path):
def analyze_dependencies(): def analyze_dependencies():
"""Analyze all dependencies in the project.""" """Analyze all dependencies in the project."""
project_root = Path(__file__).parent project_root = Path(__file__).parent
claude_rag_dir = project_root / "claude_rag" mini_rag_dir = project_root / "mini_rag"
# Find all Python files # Find all Python files
python_files = [] python_files = []
for file_path in claude_rag_dir.glob("*.py"): for file_path in mini_rag_dir.glob("*.py"):
if file_path.name != "__pycache__": if file_path.name != "__pycache__":
python_files.append(file_path) python_files.append(file_path)

View File

@ -5,7 +5,7 @@ Shows how to index a project and search it programmatically.
""" """
from pathlib import Path from pathlib import Path
from claude_rag import ProjectIndexer, CodeSearcher, CodeEmbedder from mini_rag import ProjectIndexer, CodeSearcher, CodeEmbedder
def main(): def main():
# Example project path - change this to your project # Example project path - change this to your project

View File

@ -1,6 +1,6 @@
# 🚀 BEGINNER CONFIG - Simple & Reliable # 🚀 BEGINNER CONFIG - Simple & Reliable
# Perfect for newcomers who want everything to "just work" # Perfect for newcomers who want everything to "just work"
# Copy this to your project: cp examples/config-beginner.yaml /path/to/project/.claude-rag/config.yaml # Copy this to your project: cp examples/config-beginner.yaml /path/to/project/.mini-rag/config.yaml
#═══════════════════════════════════════════════════════════════════════ #═══════════════════════════════════════════════════════════════════════
# ✨ BEGINNER-FRIENDLY SETTINGS - No overwhelming options! # ✨ BEGINNER-FRIENDLY SETTINGS - No overwhelming options!
@ -65,7 +65,7 @@ llm:
# ✅ AI features available but not overwhelming # ✅ AI features available but not overwhelming
# #
# 🚀 TO GET STARTED: # 🚀 TO GET STARTED:
# 1. Copy this file to your project: .claude-rag/config.yaml # 1. Copy this file to your project: .mini-rag/config.yaml
# 2. Index your project: ./rag-mini index /path/to/project # 2. Index your project: ./rag-mini index /path/to/project
# 3. Search: ./rag-mini search /path/to/project "your query" # 3. Search: ./rag-mini search /path/to/project "your query"
# 4. Try AI: ./rag-mini search /path/to/project "your query" --synthesize # 4. Try AI: ./rag-mini search /path/to/project "your query" --synthesize

View File

@ -99,7 +99,7 @@ llm:
# • CI/CD environments where speed matters # • CI/CD environments where speed matters
# #
# 🚀 TO USE THIS CONFIG: # 🚀 TO USE THIS CONFIG:
# 1. Copy to project: cp examples/config-fast.yaml .claude-rag/config.yaml # 1. Copy to project: cp examples/config-fast.yaml .mini-rag/config.yaml
# 2. Index: ./rag-mini index /path/to/project # 2. Index: ./rag-mini index /path/to/project
# 3. Enjoy lightning-fast searches! ⚡ # 3. Enjoy lightning-fast searches! ⚡
#═══════════════════════════════════════════════════════════════════════ #═══════════════════════════════════════════════════════════════════════

View File

@ -92,7 +92,7 @@ llm:
# 1. Install Ollama: curl -fsSL https://ollama.ai/install.sh | sh # 1. Install Ollama: curl -fsSL https://ollama.ai/install.sh | sh
# 2. Start Ollama: ollama serve # 2. Start Ollama: ollama serve
# 3. Install a model: ollama pull qwen3:1.7b # 3. Install a model: ollama pull qwen3:1.7b
# 4. Copy config: cp examples/config-quality.yaml .claude-rag/config.yaml # 4. Copy config: cp examples/config-quality.yaml .mini-rag/config.yaml
# 5. Index project: ./rag-mini index /path/to/project # 5. Index project: ./rag-mini index /path/to/project
# 6. Enjoy comprehensive analysis: ./rag-mini explore /path/to/project # 6. Enjoy comprehensive analysis: ./rag-mini explore /path/to/project
#═══════════════════════════════════════════════════════════════════════ #═══════════════════════════════════════════════════════════════════════

View File

@ -492,7 +492,7 @@ test_installation() {
print_info "Testing basic functionality..." print_info "Testing basic functionality..."
# Test import # Test import
if python3 -c "from claude_rag import CodeEmbedder, ProjectIndexer, CodeSearcher; print('✅ Import successful')" 2>/dev/null; then if python3 -c "from mini_rag import CodeEmbedder, ProjectIndexer, CodeSearcher; print('✅ Import successful')" 2>/dev/null; then
print_success "Python imports working" print_success "Python imports working"
else else
print_error "Import test failed" print_error "Import test failed"
@ -501,7 +501,7 @@ test_installation() {
# Test embedding system # Test embedding system
if python3 -c " if python3 -c "
from claude_rag import CodeEmbedder from mini_rag import CodeEmbedder
embedder = CodeEmbedder() embedder = CodeEmbedder()
info = embedder.get_embedding_info() info = embedder.get_embedding_info()
print(f'✅ Embedding system: {info[\"method\"]}') print(f'✅ Embedding system: {info[\"method\"]}')

6
mini_rag/__main__.py Normal file
View File

@ -0,0 +1,6 @@
"""Main entry point for mini_rag module."""
from .cli import cli
if __name__ == '__main__':
cli()

View File

@ -16,7 +16,7 @@ class AutoOptimizer:
def __init__(self, project_path: Path): def __init__(self, project_path: Path):
self.project_path = project_path self.project_path = project_path
self.rag_dir = project_path / '.claude-rag' self.rag_dir = project_path / '.mini-rag'
self.config_path = self.rag_dir / 'config.json' self.config_path = self.rag_dir / 'config.json'
self.manifest_path = self.rag_dir / 'manifest.json' self.manifest_path = self.rag_dir / 'manifest.json'

View File

@ -1,6 +1,6 @@
""" """
Command-line interface for Claude RAG system. Command-line interface for Mini RAG system.
Beautiful, intuitive, and fucking powerful. Beautiful, intuitive, and highly effective.
""" """
import click import click
@ -47,9 +47,9 @@ console = Console()
@click.option('--quiet', '-q', is_flag=True, help='Suppress output') @click.option('--quiet', '-q', is_flag=True, help='Suppress output')
def cli(verbose: bool, quiet: bool): def cli(verbose: bool, quiet: bool):
""" """
Claude RAG - Fast semantic code search that actually works. Mini RAG - Fast semantic code search that actually works.
A local RAG system for improving Claude Code's grounding capabilities. A local RAG system for improving the development environment's grounding capabilities.
Indexes your codebase and enables lightning-fast semantic search. Indexes your codebase and enables lightning-fast semantic search.
""" """
if verbose: if verbose:
@ -71,10 +71,10 @@ def init(path: str, force: bool, reindex: bool, model: Optional[str]):
"""Initialize RAG index for a project.""" """Initialize RAG index for a project."""
project_path = Path(path).resolve() project_path = Path(path).resolve()
console.print(f"\n[bold cyan]Initializing Claude RAG for:[/bold cyan] {project_path}\n") console.print(f"\n[bold cyan]Initializing Mini RAG for:[/bold cyan] {project_path}\n")
# Check if already initialized # Check if already initialized
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
force_reindex = force or reindex force_reindex = force or reindex
if rag_dir.exists() and not force_reindex: if rag_dir.exists() and not force_reindex:
console.print("[yellow][/yellow] Project already initialized!") console.print("[yellow][/yellow] Project already initialized!")
@ -131,9 +131,9 @@ def init(path: str, force: bool, reindex: bool, model: Optional[str]):
# Show how to use # Show how to use
console.print("\n[bold]Next steps:[/bold]") console.print("\n[bold]Next steps:[/bold]")
console.print(" • Search your code: [cyan]claude-rag search \"your query\"[/cyan]") console.print(" • Search your code: [cyan]mini-rag search \"your query\"[/cyan]")
console.print(" • Watch for changes: [cyan]claude-rag watch[/cyan]") console.print(" • Watch for changes: [cyan]mini-rag watch[/cyan]")
console.print(" • View statistics: [cyan]claude-rag stats[/cyan]\n") console.print(" • View statistics: [cyan]mini-rag stats[/cyan]\n")
except Exception as e: except Exception as e:
console.print(f"\n[bold red]Error:[/bold red] {e}") console.print(f"\n[bold red]Error:[/bold red] {e}")
@ -160,9 +160,9 @@ def search(query: str, path: str, top_k: int, type: tuple, lang: tuple, show_con
project_path = Path(path).resolve() project_path = Path(path).resolve()
# Check if indexed # Check if indexed
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
console.print("[red]Error:[/red] Project not indexed. Run 'claude-rag init' first.") console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.")
sys.exit(1) sys.exit(1)
# Get performance monitor # Get performance monitor
@ -258,7 +258,7 @@ def search(query: str, path: str, top_k: int, type: tuple, lang: tuple, show_con
# Show performance summary # Show performance summary
if monitor: if monitor:
monitor.print_summary() monitor.print_summary()
console.print(" • Check if files are indexed with 'claude-rag stats'") console.print(" • Check if files are indexed with 'mini-rag stats'")
except Exception as e: except Exception as e:
console.print(f"\n[bold red]Search error:[/bold red] {e}") console.print(f"\n[bold red]Search error:[/bold red] {e}")
@ -274,9 +274,9 @@ def stats(path: str):
project_path = Path(path).resolve() project_path = Path(path).resolve()
# Check if indexed # Check if indexed
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
console.print("[red]Error:[/red] Project not indexed. Run 'claude-rag init' first.") console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.")
sys.exit(1) sys.exit(1)
try: try:
@ -343,7 +343,7 @@ def debug_schema(path: str):
project_path = Path(path).resolve() project_path = Path(path).resolve()
try: try:
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
console.print("[red]No RAG index found. Run 'init' first.[/red]") console.print("[red]No RAG index found. Run 'init' first.[/red]")
@ -406,10 +406,10 @@ def watch(path: str, delay: float, silent: bool):
project_path = Path(path).resolve() project_path = Path(path).resolve()
# Check if indexed # Check if indexed
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
if not silent: if not silent:
console.print("[red]Error:[/red] Project not indexed. Run 'claude-rag init' first.") console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.")
sys.exit(1) sys.exit(1)
try: try:
@ -532,9 +532,9 @@ def update(path: str):
project_path = Path(path).resolve() project_path = Path(path).resolve()
# Check if indexed # Check if indexed
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
console.print("[red]Error:[/red] Project not indexed. Run 'claude-rag init' first.") console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.")
sys.exit(1) sys.exit(1)
try: try:
@ -558,21 +558,21 @@ def update(path: str):
@cli.command() @cli.command()
@click.option('--show-code', '-c', is_flag=True, help='Show example code') @click.option('--show-code', '-c', is_flag=True, help='Show example code')
def info(show_code: bool): def info(show_code: bool):
"""Show information about Claude RAG.""" """Show information about Mini RAG."""
# Create info panel # Create info panel
info_text = """ info_text = """
[bold cyan]Claude RAG[/bold cyan] - Local Semantic Code Search [bold cyan]Mini RAG[/bold cyan] - Local Semantic Code Search
[bold]Features:[/bold] [bold]Features:[/bold]
Fast code indexing with AST-aware chunking Fast code indexing with AST-aware chunking
Semantic search using CodeBERT embeddings Semantic search using CodeBERT embeddings
Real-time file watching and incremental updates Real-time file watching and incremental updates
Language-aware parsing for Python, JS, Go, and more Language-aware parsing for Python, JS, Go, and more
MCP integration for Claude Code MCP integration for the development environment
[bold]How it works:[/bold] [bold]How it works:[/bold]
1. Indexes your codebase into semantic chunks 1. Indexes your codebase into semantic chunks
2. Stores vectors locally in .claude-rag/ directory 2. Stores vectors locally in .mini-rag/ directory
3. Enables natural language search across your code 3. Enables natural language search across your code
4. Updates automatically as you modify files 4. Updates automatically as you modify files
@ -582,28 +582,28 @@ def info(show_code: bool):
Storage: ~200MB for 10k files Storage: ~200MB for 10k files
""" """
panel = Panel(info_text, title="About Claude RAG", border_style="cyan") panel = Panel(info_text, title="About Mini RAG", border_style="cyan")
console.print(panel) console.print(panel)
if show_code: if show_code:
console.print("\n[bold]Example Usage:[/bold]\n") console.print("\n[bold]Example Usage:[/bold]\n")
code = """# Initialize a project code = """# Initialize a project
claude-rag init mini-rag init
# Search for code # Search for code
claude-rag search "database connection" mini-rag search "database connection"
claude-rag search "auth middleware" --type function mini-rag search "auth middleware" --type function
# Find specific functions or classes # Find specific functions or classes
claude-rag find-function connect_to_db mini-rag find-function connect_to_db
claude-rag find-class UserModel mini-rag find-class UserModel
# Watch for changes # Watch for changes
claude-rag watch mini-rag watch
# Get statistics # Get statistics
claude-rag stats""" mini-rag stats"""
syntax = Syntax(code, "bash", theme="monokai") syntax = Syntax(code, "bash", theme="monokai")
console.print(syntax) console.print(syntax)
@ -619,9 +619,9 @@ def server(path: str, port: int):
project_path = Path(path).resolve() project_path = Path(path).resolve()
# Check if indexed # Check if indexed
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
console.print("[red]Error:[/red] Project not indexed. Run 'claude-rag init' first.") console.print("[red]Error:[/red] Project not indexed. Run 'mini-rag init' first.")
sys.exit(1) sys.exit(1)
try: try:
@ -667,7 +667,7 @@ def status(path: str, port: int, discovery: bool):
# Check index status # Check index status
console.print("\n[bold]🗂️ Index Status:[/bold]") console.print("\n[bold]🗂️ Index Status:[/bold]")
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if rag_dir.exists(): if rag_dir.exists():
try: try:
indexer = ProjectIndexer(project_path) indexer = ProjectIndexer(project_path)

View File

@ -111,7 +111,7 @@ class ConfigManager:
def __init__(self, project_path: Path): def __init__(self, project_path: Path):
self.project_path = Path(project_path) self.project_path = Path(project_path)
self.rag_dir = self.project_path / '.claude-rag' self.rag_dir = self.project_path / '.mini-rag'
self.config_path = self.rag_dir / 'config.yaml' self.config_path = self.rag_dir / 'config.yaml'
def load_config(self) -> RAGConfig: def load_config(self) -> RAGConfig:

View File

@ -8,7 +8,7 @@ Drop-in replacement for the original server with:
- Comprehensive health checks and status monitoring - Comprehensive health checks and status monitoring
- Enhanced error handling and recovery - Enhanced error handling and recovery
- Better indexing progress reporting - Better indexing progress reporting
- Claude-friendly status updates - Mini-RAG-friendly status updates
""" """
import json import json
@ -206,7 +206,7 @@ class FastRAGServer:
def _check_indexing_needed(self) -> bool: def _check_indexing_needed(self) -> bool:
"""Quick check if indexing is needed""" """Quick check if indexing is needed"""
rag_dir = self.project_path / '.claude-rag' rag_dir = self.project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
return True return True
@ -492,7 +492,7 @@ class FastRAGServer:
f"📁 Project: {self.project_path.name}\n" f"📁 Project: {self.project_path.name}\n"
f"🧠 Model: {getattr(self.embedder, 'model_name', 'default')}\n" f"🧠 Model: {getattr(self.embedder, 'model_name', 'default')}\n"
f"📊 Chunks Indexed: {self.status.health_checks.get('database', {}).get('chunks', 0)}\n\n" f"📊 Chunks Indexed: {self.status.health_checks.get('database', {}).get('chunks', 0)}\n\n"
f"[dim]Ready to serve Claude Code queries...[/dim]", f"[dim]Ready to serve the development environment queries...[/dim]",
title="🚀 Server Status", title="🚀 Server Status",
border_style="green" border_style="green"
) )
@ -698,7 +698,7 @@ class FastRAGClient:
except ConnectionRefusedError: except ConnectionRefusedError:
return { return {
'success': False, 'success': False,
'error': 'RAG server not running. Start with: python -m claude_rag server', 'error': 'RAG server not running. Start with: python -m mini_rag server',
'error_type': 'connection_refused' 'error_type': 'connection_refused'
} }
except socket.timeout: except socket.timeout:

View File

@ -44,7 +44,7 @@ class ProjectIndexer:
max_workers: Number of parallel workers for indexing max_workers: Number of parallel workers for indexing
""" """
self.project_path = Path(project_path).resolve() self.project_path = Path(project_path).resolve()
self.rag_dir = self.project_path / '.claude-rag' self.rag_dir = self.project_path / '.mini-rag'
self.manifest_path = self.rag_dir / 'manifest.json' self.manifest_path = self.rag_dir / 'manifest.json'
self.config_path = self.rag_dir / 'config.json' self.config_path = self.rag_dir / 'config.json'

View File

@ -68,11 +68,14 @@ class LLMSynthesizer:
# Modern model preference ranking (CPU-friendly first) # Modern model preference ranking (CPU-friendly first)
# Prioritize: Ultra-efficient > Standard efficient > Larger models # Prioritize: Ultra-efficient > Standard efficient > Larger models
model_rankings = [ model_rankings = [
# Recommended model (excellent quality)
"qwen3:4b",
# Ultra-efficient models (perfect for CPU-only systems) # Ultra-efficient models (perfect for CPU-only systems)
"qwen3:0.6b", "qwen3:1.7b", "llama3.2:1b", "qwen3:0.6b", "qwen3:1.7b", "llama3.2:1b",
# Standard efficient models # Standard efficient models
"qwen2.5:1.5b", "qwen3:3b", "qwen3:4b", "qwen2.5:1.5b", "qwen3:3b",
# Qwen2.5 models (excellent performance/size ratio) # Qwen2.5 models (excellent performance/size ratio)
"qwen2.5-coder:1.5b", "qwen2.5:1.5b", "qwen2.5:3b", "qwen2.5-coder:3b", "qwen2.5-coder:1.5b", "qwen2.5:1.5b", "qwen2.5:3b", "qwen2.5-coder:3b",

View File

@ -1,7 +1,7 @@
""" """
Cross-platform path handler for the RAG system. Cross-platform path handler for the RAG system.
Handles forward/backward slashes on any file system. Handles forward/backward slashes on any file system.
No more path bullshit! Robust cross-platform path handling.
""" """
import os import os

View File

@ -15,8 +15,8 @@ Example: "authentication" becomes "authentication login user verification creden
## Usage ## Usage
```python ```python
from claude_rag.query_expander import QueryExpander from mini_rag.query_expander import QueryExpander
from claude_rag.config import RAGConfig from mini_rag.config import RAGConfig
config = RAGConfig() config = RAGConfig()
expander = QueryExpander(config) expander = QueryExpander(config)

View File

@ -96,7 +96,7 @@ class CodeSearcher:
embedder: CodeEmbedder instance (creates one if not provided) embedder: CodeEmbedder instance (creates one if not provided)
""" """
self.project_path = Path(project_path).resolve() self.project_path = Path(project_path).resolve()
self.rag_dir = self.project_path / '.claude-rag' self.rag_dir = self.project_path / '.mini-rag'
self.embedder = embedder or CodeEmbedder() self.embedder = embedder or CodeEmbedder()
# Load configuration and initialize query expander # Load configuration and initialize query expander

View File

@ -272,7 +272,7 @@ class RAGClient:
except ConnectionRefusedError: except ConnectionRefusedError:
return { return {
'success': False, 'success': False,
'error': 'RAG server not running. Start with: claude-rag server' 'error': 'RAG server not running. Start with: mini-rag server'
} }
except ConnectionError as e: except ConnectionError as e:
# Try legacy mode without message framing # Try legacy mode without message framing
@ -389,7 +389,7 @@ def auto_start_if_needed(project_path: Path) -> Optional[subprocess.Popen]:
if not client.is_running(): if not client.is_running():
# Start server in background # Start server in background
import subprocess import subprocess
cmd = [sys.executable, "-m", "claude_rag.cli", "server", "--path", str(project_path)] cmd = [sys.executable, "-m", "mini_rag.cli", "server", "--path", str(project_path)]
process = subprocess.Popen( process = subprocess.Popen(
cmd, cmd,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,

View File

@ -1,6 +1,6 @@
""" """
Windows Console Unicode/Emoji Fix Windows Console Unicode/Emoji Fix
This fucking works in 2025. No more emoji bullshit. Reliable Windows console Unicode/emoji support for 2025.
""" """
import sys import sys

View File

@ -15,11 +15,11 @@ import logging
# Add the RAG system to the path # Add the RAG system to the path
sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(Path(__file__).parent))
from claude_rag.indexer import ProjectIndexer from mini_rag.indexer import ProjectIndexer
from claude_rag.search import CodeSearcher from mini_rag.search import CodeSearcher
from claude_rag.ollama_embeddings import OllamaEmbedder from mini_rag.ollama_embeddings import OllamaEmbedder
from claude_rag.llm_synthesizer import LLMSynthesizer from mini_rag.llm_synthesizer import LLMSynthesizer
from claude_rag.explorer import CodeExplorer from mini_rag.explorer import CodeExplorer
# Configure logging for user-friendly output # Configure logging for user-friendly output
logging.basicConfig( logging.basicConfig(
@ -36,7 +36,7 @@ def index_project(project_path: Path, force: bool = False):
print(f"🚀 {action} {project_path.name}") print(f"🚀 {action} {project_path.name}")
# Quick pre-check # Quick pre-check
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if rag_dir.exists() and not force: if rag_dir.exists() and not force:
print(" Checking for changes...") print(" Checking for changes...")
@ -65,7 +65,7 @@ def index_project(project_path: Path, force: bool = False):
print(f"⚠️ {failed_count} files failed (check logs with --verbose)") print(f"⚠️ {failed_count} files failed (check logs with --verbose)")
# Quick tip for first-time users # Quick tip for first-time users
if not (project_path / '.claude-rag' / 'last_search').exists(): if not (project_path / '.mini-rag' / 'last_search').exists():
print(f"\n💡 Try: rag-mini search {project_path} \"your search here\"") print(f"\n💡 Try: rag-mini search {project_path} \"your search here\"")
except Exception as e: except Exception as e:
@ -86,7 +86,7 @@ def search_project(project_path: Path, query: str, limit: int = 10, synthesize:
"""Search a project directory.""" """Search a project directory."""
try: try:
# Check if indexed first # Check if indexed first
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
print(f"❌ Project not indexed: {project_path.name}") print(f"❌ Project not indexed: {project_path.name}")
print(f" Run: rag-mini index {project_path}") print(f" Run: rag-mini index {project_path}")
@ -117,7 +117,12 @@ def search_project(project_path: Path, query: str, limit: int = 10, synthesize:
for i, result in enumerate(results, 1): for i, result in enumerate(results, 1):
# Clean up file path display # Clean up file path display
rel_path = result.file_path.relative_to(project_path) if result.file_path.is_absolute() else result.file_path file_path = Path(result.file_path)
try:
rel_path = file_path.relative_to(project_path)
except ValueError:
# If relative_to fails, just show the basename
rel_path = file_path.name
print(f"{i}. {rel_path}") print(f"{i}. {rel_path}")
print(f" Score: {result.score:.3f}") print(f" Score: {result.score:.3f}")
@ -180,7 +185,7 @@ def search_project(project_path: Path, query: str, limit: int = 10, synthesize:
else: else:
print("🔧 Common solutions:") print("🔧 Common solutions:")
print(" • Check project path exists and is readable") print(" • Check project path exists and is readable")
print(" • Verify index isn't corrupted: delete .claude-rag/ and re-index") print(" • Verify index isn't corrupted: delete .mini-rag/ and re-index")
print(" • Try with a different project to test setup") print(" • Try with a different project to test setup")
print(" • Check available memory and disk space") print(" • Check available memory and disk space")
print() print()
@ -197,7 +202,7 @@ def status_check(project_path: Path):
print() print()
# Check project indexing status first # Check project indexing status first
rag_dir = project_path / '.claude-rag' rag_dir = project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
print("❌ Project not indexed") print("❌ Project not indexed")
print(f" Run: rag-mini index {project_path}") print(f" Run: rag-mini index {project_path}")
@ -236,7 +241,7 @@ def status_check(project_path: Path):
print("🧠 Embedding System:") print("🧠 Embedding System:")
try: try:
embedder = OllamaEmbedder() embedder = OllamaEmbedder()
emb_info = embedder.get_embedding_info() emb_info = embedder.get_status()
method = emb_info.get('method', 'unknown') method = emb_info.get('method', 'unknown')
if method == 'ollama': if method == 'ollama':

View File

@ -136,7 +136,7 @@ class SimpleTUI:
print("=================") print("=================")
print() print()
# Look for .claude-rag directories in common locations # Look for .mini-rag directories in common locations
search_paths = [ search_paths = [
Path.home(), Path.home(),
Path.home() / "projects", Path.home() / "projects",
@ -152,7 +152,7 @@ class SimpleTUI:
try: try:
for item in search_path.iterdir(): for item in search_path.iterdir():
if item.is_dir(): if item.is_dir():
rag_dir = item / '.claude-rag' rag_dir = item / '.mini-rag'
if rag_dir.exists(): if rag_dir.exists():
recent_projects.append(item) recent_projects.append(item)
except (PermissionError, OSError): except (PermissionError, OSError):
@ -161,19 +161,19 @@ class SimpleTUI:
# Remove duplicates and sort by modification time # Remove duplicates and sort by modification time
recent_projects = list(set(recent_projects)) recent_projects = list(set(recent_projects))
try: try:
recent_projects.sort(key=lambda p: (p / '.claude-rag').stat().st_mtime, reverse=True) recent_projects.sort(key=lambda p: (p / '.mini-rag').stat().st_mtime, reverse=True)
except: except:
pass pass
if not recent_projects: if not recent_projects:
print("❌ No recently indexed projects found") print("❌ No recently indexed projects found")
print(" Projects with .claude-rag directories will appear here") print(" Projects with .mini-rag directories will appear here")
return return
print("Found indexed projects:") print("Found indexed projects:")
for i, project in enumerate(recent_projects[:10], 1): # Show up to 10 for i, project in enumerate(recent_projects[:10], 1): # Show up to 10
try: try:
manifest = project / '.claude-rag' / 'manifest.json' manifest = project / '.mini-rag' / 'manifest.json'
if manifest.exists(): if manifest.exists():
with open(manifest) as f: with open(manifest) as f:
data = json.load(f) data = json.load(f)
@ -211,7 +211,7 @@ class SimpleTUI:
print() print()
# Check if already indexed # Check if already indexed
rag_dir = self.project_path / '.claude-rag' rag_dir = self.project_path / '.mini-rag'
if rag_dir.exists(): if rag_dir.exists():
print("⚠️ Project appears to be already indexed") print("⚠️ Project appears to be already indexed")
print() print()
@ -233,7 +233,7 @@ class SimpleTUI:
try: try:
# Import here to avoid startup delays # Import here to avoid startup delays
sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(Path(__file__).parent))
from claude_rag.indexer import ProjectIndexer from mini_rag.indexer import ProjectIndexer
indexer = ProjectIndexer(self.project_path) indexer = ProjectIndexer(self.project_path)
result = indexer.index_project(force_reindex=force) result = indexer.index_project(force_reindex=force)
@ -262,7 +262,7 @@ class SimpleTUI:
return return
# Check if indexed # Check if indexed
rag_dir = self.project_path / '.claude-rag' rag_dir = self.project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
print(f"❌ Project not indexed: {self.project_path.name}") print(f"❌ Project not indexed: {self.project_path.name}")
print(" Index the project first!") print(" Index the project first!")
@ -303,7 +303,7 @@ class SimpleTUI:
# Actually run the search # Actually run the search
try: try:
sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(Path(__file__).parent))
from claude_rag.search import CodeSearcher from mini_rag.search import CodeSearcher
searcher = CodeSearcher(self.project_path) searcher = CodeSearcher(self.project_path)
# Enable query expansion in TUI for better results # Enable query expansion in TUI for better results
@ -372,7 +372,7 @@ class SimpleTUI:
return return
# Check if indexed # Check if indexed
rag_dir = self.project_path / '.claude-rag' rag_dir = self.project_path / '.mini-rag'
if not rag_dir.exists(): if not rag_dir.exists():
print(f"❌ Project not indexed: {self.project_path.name}") print(f"❌ Project not indexed: {self.project_path.name}")
print(" Index the project first!") print(" Index the project first!")
@ -403,7 +403,7 @@ class SimpleTUI:
# Launch exploration mode # Launch exploration mode
try: try:
sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(Path(__file__).parent))
from claude_rag.explorer import CodeExplorer from mini_rag.explorer import CodeExplorer
explorer = CodeExplorer(self.project_path) explorer = CodeExplorer(self.project_path)
@ -483,7 +483,7 @@ class SimpleTUI:
self.print_cli_command(cli_cmd, "Show detailed status information") self.print_cli_command(cli_cmd, "Show detailed status information")
# Check project status # Check project status
rag_dir = self.project_path / '.claude-rag' rag_dir = self.project_path / '.mini-rag'
if rag_dir.exists(): if rag_dir.exists():
try: try:
manifest = rag_dir / 'manifest.json' manifest = rag_dir / 'manifest.json'
@ -511,10 +511,10 @@ class SimpleTUI:
# Show embedding system status # Show embedding system status
try: try:
sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(Path(__file__).parent))
from claude_rag.ollama_embeddings import OllamaEmbedder from mini_rag.ollama_embeddings import OllamaEmbedder
embedder = OllamaEmbedder() embedder = OllamaEmbedder()
info = embedder.get_embedding_info() info = embedder.get_status()
print("🧠 Embedding System:") print("🧠 Embedding System:")
method = info.get('method', 'unknown') method = info.get('method', 'unknown')
@ -549,7 +549,7 @@ class SimpleTUI:
print(f"Project: {self.project_path.name}") print(f"Project: {self.project_path.name}")
print() print()
config_path = self.project_path / '.claude-rag' / 'config.yaml' config_path = self.project_path / '.mini-rag' / 'config.yaml'
# Show current configuration if it exists # Show current configuration if it exists
if config_path.exists(): if config_path.exists():
@ -678,7 +678,7 @@ class SimpleTUI:
# Show current project status # Show current project status
if self.project_path: if self.project_path:
rag_dir = self.project_path / '.claude-rag' rag_dir = self.project_path / '.mini-rag'
status = "✅ Indexed" if rag_dir.exists() else "❌ Not indexed" status = "✅ Indexed" if rag_dir.exists() else "❌ Not indexed"
print(f"📁 Current project: {self.project_path.name} ({status})") print(f"📁 Current project: {self.project_path.name} ({status})")
print() print()

View File

@ -13,7 +13,7 @@
- **Helpful error messages**: In `rag-mini.py`, errors like "❌ Project not indexed" include the solution: "Run: rag-mini index /path/to/project" - **Helpful error messages**: In `rag-mini.py`, errors like "❌ Project not indexed" include the solution: "Run: rag-mini index /path/to/project"
### **Excellent Code Organization** ### **Excellent Code Organization**
- **Clean module structure**: `claude_rag/` contains all the core code with logical names like `chunker.py`, `search.py`, `indexer.py` - **Clean module structure**: `mini_rag/` contains all the core code with logical names like `chunker.py`, `search.py`, `indexer.py`
- **Single responsibility**: Each file does one main thing - the chunker chunks, the searcher searches, etc. - **Single responsibility**: Each file does one main thing - the chunker chunks, the searcher searches, etc.
- **Good naming**: Functions like `index_project()`, `search_project()`, `status_check()` are self-explanatory - **Good naming**: Functions like `index_project()`, `search_project()`, `status_check()` are self-explanatory

View File

@ -1,4 +1,4 @@
# Full Claude RAG - With ML Fallback # Full Mini RAG - With ML Fallback
# Base lightweight dependencies + ML stack for offline use # Base lightweight dependencies + ML stack for offline use
# Lightweight dependencies (always required) # Lightweight dependencies (always required)

View File

@ -1,4 +1,4 @@
# Lightweight Claude RAG - Ollama Edition # Lightweight Mini RAG - Ollama Edition
# Removed: torch, transformers, sentence-transformers (5.2GB+ saved) # Removed: torch, transformers, sentence-transformers (5.2GB+ saved)
# Core vector database and data handling # Core vector database and data handling

View File

@ -12,10 +12,10 @@ if sys.platform == 'win32':
os.environ['PYTHONUTF8'] = '1' os.environ['PYTHONUTF8'] = '1'
sys.stdout.reconfigure(encoding='utf-8') sys.stdout.reconfigure(encoding='utf-8')
from claude_rag.chunker import CodeChunker from mini_rag.chunker import CodeChunker
from claude_rag.indexer import ProjectIndexer from mini_rag.indexer import ProjectIndexer
from claude_rag.search import CodeSearcher from mini_rag.search import CodeSearcher
from claude_rag.embeddings import CodeEmbedder from mini_rag.embeddings import CodeEmbedder
def main(): def main():
print("=" * 60) print("=" * 60)

View File

@ -10,7 +10,7 @@ from rich.syntax import Syntax
from rich.panel import Panel from rich.panel import Panel
from rich.table import Table from rich.table import Table
from claude_rag.search import CodeSearcher from mini_rag.search import CodeSearcher
console = Console() console = Console()
@ -18,7 +18,7 @@ console = Console()
def demo_search(project_path: Path): def demo_search(project_path: Path):
"""Run demo searches showing the hybrid system in action.""" """Run demo searches showing the hybrid system in action."""
console.print("\n[bold cyan]Claude RAG Hybrid Search Demo[/bold cyan]\n") console.print("\n[bold cyan]Mini RAG Hybrid Search Demo[/bold cyan]\n")
# Initialize searcher # Initialize searcher
console.print("Initializing search system...") console.print("Initializing search system...")
@ -123,9 +123,9 @@ def main():
# Use the RAG system itself as the demo project # Use the RAG system itself as the demo project
project_path = Path(__file__).parent project_path = Path(__file__).parent
if not (project_path / '.claude-rag').exists(): if not (project_path / '.mini-rag').exists():
console.print("[red]Error: No RAG index found. Run 'claude-rag index' first.[/red]") console.print("[red]Error: No RAG index found. Run 'mini-rag index' first.[/red]")
console.print(f"[dim]Looked in: {project_path / '.claude-rag'}[/dim]") console.print(f"[dim]Looked in: {project_path / '.mini-rag'}[/dim]")
return return
demo_search(project_path) demo_search(project_path)

View File

@ -12,12 +12,12 @@ if sys.platform == 'win32':
os.environ['PYTHONUTF8'] = '1' os.environ['PYTHONUTF8'] = '1'
sys.stdout.reconfigure(encoding='utf-8') sys.stdout.reconfigure(encoding='utf-8')
from claude_rag.chunker import CodeChunker from mini_rag.chunker import CodeChunker
from claude_rag.indexer import ProjectIndexer from mini_rag.indexer import ProjectIndexer
from claude_rag.search import CodeSearcher from mini_rag.search import CodeSearcher
from claude_rag.ollama_embeddings import OllamaEmbedder as CodeEmbedder from mini_rag.ollama_embeddings import OllamaEmbedder as CodeEmbedder
from claude_rag.query_expander import QueryExpander from mini_rag.query_expander import QueryExpander
from claude_rag.config import RAGConfig from mini_rag.config import RAGConfig
def test_chunker(): def test_chunker():
"""Test that chunker creates chunks with all required metadata.""" """Test that chunker creates chunks with all required metadata."""
@ -137,7 +137,7 @@ class MyClass:
''') ''')
# Index the project with small chunk size for testing # Index the project with small chunk size for testing
from claude_rag.chunker import CodeChunker from mini_rag.chunker import CodeChunker
chunker = CodeChunker(min_chunk_size=1) chunker = CodeChunker(min_chunk_size=1)
indexer = ProjectIndexer(project_path, chunker=chunker) indexer = ProjectIndexer(project_path, chunker=chunker)
stats = indexer.index_project() stats = indexer.index_project()
@ -313,7 +313,7 @@ def test_server():
# Just check if we can import and create server instance # Just check if we can import and create server instance
try: try:
from claude_rag.server import RAGServer from mini_rag.server import RAGServer
server = RAGServer(Path("."), port=7778) server = RAGServer(Path("."), port=7778)
print(" Server can be instantiated") print(" Server can be instantiated")
return True return True

View File

@ -13,7 +13,7 @@ if sys.platform == 'win32':
sys.path.insert(0, str(Path(__file__).parent)) sys.path.insert(0, str(Path(__file__).parent))
from claude_rag.vector_store import VectorStore from mini_rag.vector_store import VectorStore
from collections import Counter from collections import Counter
project_path = Path.cwd() project_path = Path.cwd()

View File

@ -4,8 +4,8 @@ Test script for adjacent chunk retrieval functionality.
""" """
from pathlib import Path from pathlib import Path
from claude_rag.search import CodeSearcher from mini_rag.search import CodeSearcher
from claude_rag.embeddings import CodeEmbedder from mini_rag.embeddings import CodeEmbedder
def test_context_retrieval(): def test_context_retrieval():
"""Test the new context retrieval functionality.""" """Test the new context retrieval functionality."""

View File

@ -15,8 +15,8 @@ from rich.columns import Columns
from rich.syntax import Syntax from rich.syntax import Syntax
from rich.progress import track from rich.progress import track
from claude_rag.search import CodeSearcher, SearchResult from mini_rag.search import CodeSearcher, SearchResult
from claude_rag.embeddings import CodeEmbedder from mini_rag.embeddings import CodeEmbedder
console = Console() console = Console()
@ -320,8 +320,8 @@ def main():
else: else:
project_path = Path.cwd() project_path = Path.cwd()
if not (project_path / '.claude-rag').exists(): if not (project_path / '.mini-rag').exists():
console.print("[red]Error: No RAG index found. Run 'claude-rag index' first.[/red]") console.print("[red]Error: No RAG index found. Run 'mini-rag index' first.[/red]")
return return
# Create tester # Create tester
@ -329,7 +329,7 @@ def main():
# Run all tests # Run all tests
console.print("\n" + "="*80) console.print("\n" + "="*80)
console.print("[bold green]Claude RAG Hybrid Search Test Suite[/bold green]") console.print("[bold green]Mini RAG Hybrid Search Test Suite[/bold green]")
console.print("="*80) console.print("="*80)
# Test 1: Query type analysis # Test 1: Query type analysis

View File

@ -1,6 +1,6 @@
"""Test with smaller min_chunk_size.""" """Test with smaller min_chunk_size."""
from claude_rag.chunker import CodeChunker from mini_rag.chunker import CodeChunker
from pathlib import Path from pathlib import Path
test_code = '''"""Test module.""" test_code = '''"""Test module."""

View File

@ -16,11 +16,11 @@ from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
try: try:
from claude_rag.llm_synthesizer import LLMSynthesizer from mini_rag.llm_synthesizer import LLMSynthesizer
from claude_rag.explorer import CodeExplorer from mini_rag.explorer import CodeExplorer
from claude_rag.config import RAGConfig from mini_rag.config import RAGConfig
from claude_rag.indexer import ProjectIndexer from mini_rag.indexer import ProjectIndexer
from claude_rag.search import CodeSearcher from mini_rag.search import CodeSearcher
except ImportError as e: except ImportError as e:
print(f"❌ Could not import RAG components: {e}") print(f"❌ Could not import RAG components: {e}")
print(" This test requires the full RAG system to be installed") print(" This test requires the full RAG system to be installed")
@ -251,7 +251,7 @@ def main():
print("=" * 40) print("=" * 40)
# Check if we're in the right environment # Check if we're in the right environment
if not Path("claude_rag").exists(): if not Path("mini_rag").exists():
print("❌ Tests must be run from the FSS-Mini-RAG root directory") print("❌ Tests must be run from the FSS-Mini-RAG root directory")
sys.exit(1) sys.exit(1)

View File

@ -18,9 +18,9 @@ from unittest.mock import patch, MagicMock
# Add project to path # Add project to path
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
from claude_rag.query_expander import QueryExpander from mini_rag.query_expander import QueryExpander
from claude_rag.llm_synthesizer import LLMSynthesizer from mini_rag.llm_synthesizer import LLMSynthesizer
from claude_rag.config import RAGConfig from mini_rag.config import RAGConfig
class TestOllamaIntegration(unittest.TestCase): class TestOllamaIntegration(unittest.TestCase):
@ -68,7 +68,7 @@ class TestOllamaIntegration(unittest.TestCase):
if len(models) > 5: if len(models) > 5:
print(f" ... and {len(models)-5} more") print(f" ... and {len(models)-5} more")
else: else:
print(" ⚠️ No models found. Install with: ollama pull qwen3:1.7b") print(" ⚠️ No models found. Install with: ollama pull qwen3:4b")
self.assertTrue(True) self.assertTrue(True)
else: else:
@ -146,7 +146,7 @@ class TestOllamaIntegration(unittest.TestCase):
if not synthesizer.is_available(): if not synthesizer.is_available():
self.fail( self.fail(
"❌ No LLM models available.\n" "❌ No LLM models available.\n"
" 💡 Install a model like: ollama pull qwen3:1.7b" " 💡 Install a model like: ollama pull qwen3:4b"
) )
print(f" ✅ Found {len(synthesizer.available_models)} LLM models") print(f" ✅ Found {len(synthesizer.available_models)} LLM models")
@ -275,7 +275,7 @@ class TestOllamaIntegration(unittest.TestCase):
print("\n🧠 Testing exploration mode (with thinking)...") print("\n🧠 Testing exploration mode (with thinking)...")
try: try:
from claude_rag.explorer import CodeExplorer from mini_rag.explorer import CodeExplorer
except ImportError: except ImportError:
self.skipTest("⏭️ CodeExplorer not available") self.skipTest("⏭️ CodeExplorer not available")
@ -312,7 +312,7 @@ class TestOllamaIntegration(unittest.TestCase):
synthesizer = LLMSynthesizer(enable_thinking=False) synthesizer = LLMSynthesizer(enable_thinking=False)
try: try:
from claude_rag.explorer import CodeExplorer from mini_rag.explorer import CodeExplorer
explorer = CodeExplorer(Path("."), self.config) explorer = CodeExplorer(Path("."), self.config)
except ImportError: except ImportError:
self.skipTest("⏭️ CodeExplorer not available") self.skipTest("⏭️ CodeExplorer not available")
@ -426,7 +426,7 @@ def run_troubleshooting():
print("💡 Common Solutions:") print("💡 Common Solutions:")
print(" • Install Ollama: https://ollama.ai/download") print(" • Install Ollama: https://ollama.ai/download")
print(" • Start server: ollama serve") print(" • Start server: ollama serve")
print(" • Install models: ollama pull qwen3:1.7b") print(" • Install models: ollama pull qwen3:4b")
print(" • Install embedding model: ollama pull nomic-embed-text") print(" • Install embedding model: ollama pull nomic-embed-text")
print() print()
print("📚 For more help, see docs/QUERY_EXPANSION.md") print("📚 For more help, see docs/QUERY_EXPANSION.md")

View File

@ -4,8 +4,8 @@
import tempfile import tempfile
import shutil import shutil
from pathlib import Path from pathlib import Path
from claude_rag.indexer import ProjectIndexer from mini_rag.indexer import ProjectIndexer
from claude_rag.search import CodeSearcher from mini_rag.search import CodeSearcher
# Sample Python file with proper structure # Sample Python file with proper structure
sample_code = '''""" sample_code = '''"""
@ -127,7 +127,7 @@ Markdown files are chunked by sections with:
### Basic Example ### Basic Example
```python ```python
from claude_rag import ProjectIndexer from mini_rag import ProjectIndexer
indexer = ProjectIndexer("/path/to/project") indexer = ProjectIndexer("/path/to/project")
indexer.index_project() indexer.index_project()
@ -138,7 +138,7 @@ indexer.index_project()
You can customize the chunking behavior: You can customize the chunking behavior:
```python ```python
from claude_rag import CodeChunker from mini_rag import CodeChunker
chunker = CodeChunker( chunker = CodeChunker(
max_chunk_size=1000, max_chunk_size=1000,

View File

@ -17,7 +17,7 @@ from unittest.mock import patch, MagicMock
# Add project to path # Add project to path
sys.path.insert(0, str(Path(__file__).parent.parent)) sys.path.insert(0, str(Path(__file__).parent.parent))
from claude_rag.search import SearchResult, CodeSearcher from mini_rag.search import SearchResult, CodeSearcher
class TestSmartRanking(unittest.TestCase): class TestSmartRanking(unittest.TestCase):

View File

@ -50,7 +50,7 @@ def main():
print(" • Check docs/QUERY_EXPANSION.md for setup help") print(" • Check docs/QUERY_EXPANSION.md for setup help")
print(" • Ensure Ollama is installed: https://ollama.ai/download") print(" • Ensure Ollama is installed: https://ollama.ai/download")
print(" • Start Ollama server: ollama serve") print(" • Start Ollama server: ollama serve")
print(" • Install models: ollama pull qwen3:1.7b") print(" • Install models: ollama pull qwen3:4b")
def run_test(test_file): def run_test(test_file):
"""Run a specific test file.""" """Run a specific test file."""