-
Notifications
You must be signed in to change notification settings - Fork 0
Contributing
Thank you for considering contributing to NaviDuck! This document provides guidelines and instructions for contributing to the project.
Last updated: 12/22/2025
- ✨ Quick Start for Contributors
- 🔍 Finding Ways to Contribute
- 🏗️ Development Setup
- 📝 Code Guidelines
- 🎯 Feature Development
- 🐛 Bug Reports
- 📚 Documentation
- 🧪 Testing
- 🔀 Pull Request Process
- 🎖️ Recognition
- ❓ Frequently Asked Questions
# 1. Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/NaviDuck.git
cd NaviDuck
# 2. Set up development environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements-dev.txt
# 4. Run tests to ensure everything works
pytest tests/
# 5. Start NaviDuck in development mode
python naviduck.py --debug| Difficulty | Type | Good First Issues |
|---|---|---|
| Beginner | Documentation | Fix typos, improve comments, update README |
| Easy | Small Features | Add new icons, improve error messages |
| Medium | Bug Fixes | Fix search parsing, improve AI responses |
| Advanced | Core Features | Add new search engines, implement caching |
- Search Engine Improvements - Better parsing, more engines
- Testing Suite - More comprehensive tests
- Documentation - User guides, API documentation
- Error Handling - Better error messages and recovery
- Performance Optimizations - Caching, faster parsing
- UI Improvements - Better navigation, more shortcuts
- Platform Support - Better macOS/Linux compatibility
- Plugin System - Extensibility framework
- Advanced Features - Tabs, downloads, sync
| Label | Meaning | Good For |
|---|---|---|
good first issue |
Beginner-friendly | New contributors |
help wanted |
Needs community help | All contributors |
bug |
Something broken | Bug hunters |
enhancement |
Feature improvement | Feature developers |
documentation |
Docs need work | Writers |
performance |
Speed improvements | Optimizers |
security |
Security issues | Security experts |
# Use GitHub search to find issues:
# https://github.com/DAPOWER99/NaviDuck/issues
# Filter by:
- is:issue is:open label:"good first issue"
- is:issue is:open label:"help wanted"
- is:issue is:open no:assignee# Fork on GitHub first, then:
git clone https://github.com/YOUR_USERNAME/NaviDuck.git
cd NaviDuck
# Add upstream remote
git remote add upstream https://github.com/DAPOWER99/NaviDuck.git# Create virtual environment
python -m venv venv
# Activate it:
# Linux/Mac:
source venv/bin/activate
# Windows:
venv\Scripts\activate
# Or use virtualenvwrapper (optional)
mkvirtualenv naviduck# Core dependencies
pip install -r requirements.txt
# Development dependencies
pip install -r requirements-dev.txt
# Or install everything:
pip install requests beautifulsoup4 colorama
pip install pytest pytest-cov black flake8 mypy
pip install pre-commit # For git hooks# Install pre-commit hooks
pre-commit install
# Set up git hooks for auto-formatting
ln -s ../../pre-commit .git/hooks/pre-commit
# Configure git for better commits
git config commit.template .gitmessage# Run all tests
pytest
# Check code quality
flake8 naviduck.py
# Run type checking (optional)
mypy naviduck.py
# Start NaviDuck in development mode
python naviduck.py --debug# .env
DEBUG=true
LOG_LEVEL=DEBUG
TEST_MODE=true
# Add API keys for testing if needed# Add to package.json or Makefile
{
"scripts": {
"test": "pytest",
"test:cov": "pytest --cov=naviduck",
"lint": "flake8 naviduck.py",
"format": "black naviduck.py",
"type": "mypy naviduck.py",
"dev": "python naviduck.py --debug",
"precommit": "pre-commit run --all-files"
}
}# ✅ Good
def search_web(query, engine="brave"):
"""Search the web using specified engine."""
results = []
# ... implementation
return results
# ❌ Bad
def SearchWeb(q, e="brave"): # Wrong naming
results=[] # Missing spaces
# ... no docstring
return results# Variables and functions: snake_case
search_results = []
def parse_html_content(): ...
# Constants: UPPER_SNAKE_CASE
MAX_RESULTS = 10
DEFAULT_ENGINE = "brave"
# Classes: PascalCase
class SearchManager: ...
class BrowserState: ...
# Private methods: _leading_underscore
def _parse_internal(): ...Module Docstring:
"""
Search Manager for NaviDuck.
Handles web search across multiple engines, parsing results,
and implementing fallback strategies for CAPTCHA and errors.
"""Function Docstring:
def search(self, query, engine=None):
"""
Search the web for a query using specified engine.
Args:
query (str): Search query string
engine (str, optional): Search engine to use. Defaults to
current_engine from BrowserState.
Returns:
List[dict]: List of search results, each containing:
- title (str): Result title
- url (str): Result URL
- snippet (str): Brief description
- engine (str): Source engine
Raises:
SearchError: If search fails across all engines
NetworkError: If network connection fails
Examples:
>>> search("python tutorial")
[{'title': 'Python Tutorial', ...}]
"""Inline Comments:
# Good: Explain why, not what
if len(results) == 0:
# Try alternative engine because main engine might be blocked
return self._fallback_search(query, engine)
# Bad: Redundant
x = x + 1 # Increment x by 1"""
Standard file layout:
1. Module docstring
2. Imports (standard lib, third-party, local)
3. Constants
4. Classes
5. Functions
6. Main guard
"""
# 1. Module docstring
"""
Search Manager Module
"""
# 2. Imports
import json
import re
import time
from typing import List, Dict, Optional
from urllib.parse import quote, urlparse
import requests
# 3. Constants
MAX_RESULTS = 10
TIMEOUT = 10
# 4. Classes
class SearchManager:
"""Main search manager class."""
pass
# 5. Functions
def helper_function():
"""Utility function."""
pass
# 6. Main guard
if __name__ == "__main__":
# Test code here
pass# 1. Standard library imports
import json
import os
import re
import sys
import time
from typing import Dict, List, Optional
from urllib.parse import quote, urlparse
# 2. Third-party imports
import requests
from colorama import init, Fore
# 3. Local application imports
# (if we had multiple files)
# from .browser_state import BrowserState
# from .network_manager import NetworkManagerclass NaviDuckError(Exception):
"""Base exception for NaviDuck."""
pass
class SearchError(NaviDuckError):
"""Search-related errors."""
pass
class NetworkError(NaviDuckError):
"""Network-related errors."""
pass
# Usage
def search(self, query, engine):
try:
return self._perform_search(query, engine)
except requests.exceptions.ConnectionError as e:
raise NetworkError(f"Connection failed: {e}") from e
except ValueError as e:
raise SearchError(f"Invalid query: {e}") from e# Good: User-friendly with recovery options
def handle_search_error(self, error):
if isinstance(error, NetworkError):
print(f"{Colors.ERROR}❌ Network error. Check your connection.{Colors.RESET}")
print(f"{Colors.INFO}Try: 1. Check internet 2. Disable firewall 3. Use Tor{Colors.RESET}")
elif isinstance(error, SearchError):
print(f"{Colors.WARNING}⚠️ Search failed. Trying alternative engine...{Colors.RESET}")
return self._fallback_search()from typing import List, Dict, Optional, Union, Tuple
def search(
self,
query: str,
engine: Optional[str] = None
) -> List[Dict[str, str]]:
"""
Search with type hints for better IDE support.
"""
results: List[Dict[str, str]] = []
# ... implementation
return results## Feature Proposal: [Feature Name]
### Description
Brief description of the feature.
### Use Case
Why is this feature needed? Who will use it?
### Proposed Implementation
How do you plan to implement it?
### API Changes
Will this change any public APIs?
### Testing Strategy
How will you test this feature?
### Dependencies
Any new dependencies required?
### Alternatives Considered
Other ways this could be implemented.- Create feature branch
- Write tests first (TDD)
- Implement core functionality
- Add error handling
- Update documentation
- Write user-facing help text
- Test on all platforms
- Performance testing
- Security review
Step 1: Research the Engine
# Check if engine has public API or search endpoint
# Example: Adding Searx search
# Test manually first:
curl "https://searx.example.com/search?q=test"Step 2: Add to SEARCH_ENGINES Dictionary
SEARCH_ENGINES = {
# ... existing engines
"searx": {
"name": "Searx",
"url": "https://searx.example.com/search",
"params": {"q": "{query}"},
"icon": "SEARCH",
"requires_tor": False,
"enabled": True,
"type": "html"
}
}Step 3: Add Parser in SearchManager
def parse_results(self, response, engine, query):
if engine == "searx":
return self._parse_searx_results(response, query)
# ... existing parsers
def _parse_searx_results(self, response, query):
"""Parse Searx search results."""
html = response.text
# Implement parsing logic
results = []
# ... parsing code
return resultsStep 4: Add Tests
def test_searx_search():
"""Test Searx search engine."""
manager = SearchManager(state, network)
# Mock response
mock_response = MockResponse(SEARX_HTML)
results = manager._parse_searx_results(mock_response, "test")
assert len(results) > 0
assert all('title' in r for r in results)
assert all('url' in r for r in results)Step 5: Update Documentation
## Searx Search
Searx is a privacy-respecting meta-search engine...
### Usage:search searx [query]
### Features:
- Privacy focused
- No tracking
- Multiple sources
# Format: type/description
git checkout -b feature/new-search-engine
git checkout -b bug/fix-captcha-detection
git checkout -b docs/improve-readme
git checkout -b test/add-search-tests
# Types:
# feature/ - New features
# bug/ - Bug fixes
# docs/ - Documentation
# test/ - Tests
# perf/ - Performance improvements
# refactor/- Code refactoring## Bug Report
### Description
[Clear description of the bug]
### Steps to Reproduce
1. Start NaviDuck with `python naviduck.py`
2. Type `s test search`
3. Observe error message
4. [Add more steps if needed]
### Expected Behavior
[What should happen]
### Actual Behavior
[What actually happens]
### Environment
- NaviDuck Version: [e.g., 1.0.0 or commit hash]
- Python Version: [e.g., 3.9.7]
- OS: [e.g., Windows 10, Ubuntu 20.04, macOS 11]
- Terminal: [e.g., Windows Terminal, iTerm2, GNOME Terminal]
### Error Message[Copy-paste full error message here]
### Screenshots/Logs
[If applicable, add screenshots or log files]
### Additional Context
[Any other information that might be relevant]
1. Search-Related Bugs:
- No results returned
- Incorrect parsing
- CAPTCHA issues
- Engine not working
2. AI-Related Bugs:
- AI not responding
- Incorrect answers
- Timeout issues
3. UI/UX Bugs:
- Display issues
- Colors/icons not showing
- Input problems
4. Network Bugs:
- Connection failures
- Timeout issues
- Proxy/Tor problems
5. Platform-Specific Bugs:
- Windows-specific issues
- Linux/macOS issues
- Terminal compatibility
# Run with debug flag
python naviduck.py --debug
# Or set environment variable
export DEBUG=true
python naviduck.py# Add to your bug report
python -c "
import sys
import platform
print(f'Python: {sys.version}')
print(f'Platform: {platform.platform()}')
print(f'System: {platform.system()} {platform.release()}')
"
# Check dependencies
pip list | grep -E "(requests|colorama)"# minimal_repro.py
import requests
# Minimal code to reproduce bug
try:
response = requests.get("https://duckduckgo.com/html?q=test", timeout=10)
print(f"Status: {response.status_code}")
print(f"Length: {len(response.text)}")
except Exception as e:
print(f"Error: {e}")"""
Module: search_manager.py
Handles all search-related functionality including:
- Querying multiple search engines
- Parsing HTML/JSON responses
- Implementing fallback strategies
- Caching search results
"""
class SearchManager:
"""
Main search manager class.
This class coordinates between different search engines,
handles parsing, and implements error recovery.
Attributes:
state (BrowserState): Current browser state
network (NetworkManager): Network request handler
cache (dict): In-memory cache for results
"""# Search Guide
## Basic Search
To search the web, simply type:s [your query]
## Advanced Search
Use specific engines:
search google python tutorial search wikipedia machine learning search ddg_api "quick answers"
## Search Operators
- Quotes for exact phrases: `"exact phrase"`
- Site restriction: `site:github.com python`
- File type: `filetype:pdf python tutorial`
# In docstrings for public APIs
def search(self, query: str, engine: str = None) -> List[Dict]:
"""
Public API: Perform web search.
This is the main search method used by the UI.
Example:
>>> manager = SearchManager(state, network)
>>> results = manager.search("python tutorial")
>>> len(results)
10
Note:
Results are cached for 5 minutes by default.
Use `clear_cache()` to force fresh results.
"""- Update Features list when adding new features
- Update Usage examples
- Update Configuration options
- Update Dependencies if changed
- Update Platform support if improved
The GitHub Wiki should contain:
- Detailed user guides
- Troubleshooting guides
- Development guides
- API reference
- FAQ
# Update help text in UIManager.show_help()
def show_help(self):
print("Available Commands:")
print(" s [query] - Quick search")
print(" search [engine] [query] - Search with specific engine")
# Add new commands here Unit Tests (70%)
↑
Integration Tests (20%)
↑
E2E Tests (10%)
# tests/test_search_manager.py
import pytest
from unittest.mock import Mock, patch
from naviduck.search_manager import SearchManager
class TestSearchManager:
def setup_method(self):
self.state = Mock()
self.network = Mock()
self.manager = SearchManager(self.state, self.network)
def test_search_valid_query(self):
"""Test search with valid query."""
# Arrange
query = "python tutorial"
expected_results = [{"title": "Python", "url": "https://python.org"}]
# Mock network response
mock_response = Mock()
mock_response.text = "<html>...</html>"
self.network.get.return_value = mock_response
# Act
results = self.manager.search(query)
# Assert
assert len(results) > 0
self.network.get.assert_called_once()
def test_search_empty_query(self):
"""Test search with empty query."""
with pytest.raises(ValueError):
self.manager.search("")
@pytest.mark.parametrize("engine", ["brave", "ddg", "google"])
def test_search_different_engines(self, engine):
"""Test search with different engines."""
results = self.manager.search("test", engine=engine)
assert isinstance(results, list)# tests/integration/test_search_flow.py
class TestSearchFlow:
def test_complete_search_flow(self):
"""Test complete search flow from UI to results."""
# Setup real components
state = BrowserState()
network = NetworkManager(state)
manager = SearchManager(state, network)
ui = UIManager(state, manager, None, None)
# Simulate user input
command = "s python tutorial"
# Execute command
result = ui.handle_command(command)
# Verify results
assert result is True
assert len(state.current_results) > 0# tests/e2e/test_user_journey.py
def test_user_search_journey():
"""Test complete user journey: search → view → bookmark."""
# This might use selenium or similar for full E2E
pass# 1. Write failing test
def test_new_feature():
assert new_feature() == expected_result
# 2. Implement feature
def new_feature():
return expected_result
# 3. Refactor and improve@patch('naviduck.search_manager.requests.get')
def test_search_with_mock(mock_get):
# Setup mock
mock_response = Mock()
mock_response.text = mock_html
mock_get.return_value = mock_response
# Test
results = manager.search("test")
# Verify
mock_get.assert_called_once()
assert len(results) == 10def test_edge_cases():
# Empty inputs
test_search_empty()
# Very long inputs
test_search_long_query("a" * 1000)
# Special characters
test_search_special_chars("test!@#$%^&*()")
# Unicode
test_search_unicode("Python 🐍")
# Network failures
test_search_network_failure()# Run all tests
pytest
# Run specific test file
pytest tests/test_search_manager.py
# Run with coverage
pytest --cov=naviduck
# Run with verbose output
pytest -v
# Run tests matching pattern
pytest -k "test_search"
# Run with specific markers
pytest -m "integration"
# Generate HTML coverage report
pytest --cov=naviduck --cov-report=html- Branch is up to date with
main - All tests pass
- Code follows style guidelines
- Documentation is updated
- No debugging code left
- Commit messages are clear
- Changes are focused (one feature/bug per PR)
## Description
[Describe the changes in this PR]
## Related Issue
Fixes #123 [Link to issue]
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
- [ ] Performance improvement
## Testing
- [ ] Added unit tests
- [ ] Added integration tests
- [ ] Tested manually
- [ ] All tests pass
## Screenshots
[If applicable, add screenshots]
## Checklist
- [ ] My code follows the style guidelines
- [ ] I have performed a self-review
- [ ] I have commented my code
- [ ] I have updated documentation
- [ ] My changes generate no new warningsgit checkout main
git fetch upstream
git merge upstream/main
git push origin maingit checkout -b feature/your-feature
# Make changes
git add .
git commit -m "feat: add new search engine"git push origin feature/your-feature
# Go to GitHub and create PR# Make requested changes
git add .
git commit -m "fix: address review comments"
# Keep PR updated
git fetch upstream
git merge upstream/main
# Resolve conflicts if any
# Push updates
git push origin feature/your-feature<type>[optional scope]: <description>
[optional body]
[optional footer]
-
feat:- New feature -
fix:- Bug fix -
docs:- Documentation -
style:- Formatting, missing semi-colons, etc. -
refactor:- Code refactoring -
test:- Adding tests -
chore:- Maintenance tasks
# Good commit messages
git commit -m "feat: add Brave search engine support"
git commit -m "fix: correct CAPTCHA detection logic"
git commit -m "docs: update search engine guide"
git commit -m "test: add tests for new search engine"
# With scope
git commit -m "feat(search): add result caching"
git commit -m "fix(ui): correct color display on Windows"-
Code Quality
- Follows style guidelines
- Well-documented
- No obvious bugs
- Error handling
-
Functionality
- Solves the problem
- No regression
- Edge cases handled
-
Testing
- Tests added/updated
- All tests pass
- Good test coverage
-
Documentation
- User docs updated
- Code comments clear
- API documentation
- Specific: Point to exact lines/issues
- Constructive: Suggest improvements
- Respectful: Professional tone
- Actionable: Clear what needs to change
- Name in CONTRIBUTORS.md
- GitHub shoutout
- Bronze benefits +
- Contributor badge in README
- Feature request priority
- Silver benefits +
- Direct commit access (after review)
- Project decision input
- Listed as core contributor
- Gold benefits +
- Co-maintainer status
- Release management privileges
- Special recognition
We recognize outstanding contributions in our CONTRIBUTORS.md file:
# NaviDuck Contributors
## Core Team
- [DAPOWER99](https://github.com/DAPOWER99) - Creator & Maintainer
## Gold Contributors
- [Contributor Name](https://github.com/username) - Major feature contributions
## Silver Contributors
- [Contributor Name](https://github.com/username) - Multiple quality contributions
## Bronze Contributors
- [Contributor Name](https://github.com/username) - Valuable contributions
## Special Thanks
- Everyone who reported issues
- All beta testers
- Documentation contributorsAdd to your GitHub profile:
[](https://github.com/DAPOWER99/NaviDuck)Q: I'm new to open source. Where should I start? A: Start with "good first issue" labeled issues or documentation improvements. Don't hesitate to ask questions!
Q: How do I get help with my contribution? A: Use GitHub Discussions or comment on the issue you're working on. The community is friendly and helpful.
Q: What if my PR gets stuck in review? A: Be patient but proactive. Politely ping reviewers after a few days, or ask if someone else can review.
Q: Can I work on multiple issues at once? A: It's better to focus on one issue per PR. If they're related, you can combine them.
Q: How do I test my changes without breaking anything? A: Write tests first, run existing tests, and test manually with different scenarios.
Q: What if I can't reproduce a bug on my system? A: Ask for more details in the issue, or try to understand the conditions that cause it.
Q: How do I handle platform-specific code?
A: Use conditionals (if os.name == 'nt':) and test on multiple platforms if possible.
Q: What's the policy on adding new dependencies? A: Keep dependencies minimal. If adding new ones, justify why they're needed and consider alternatives.
Q: How long does it take for PRs to get merged? A: It varies. Simple fixes might be merged same day, complex features might take weeks with multiple reviews.
Q: What if my PR conflicts with another PR? A: We'll help you resolve conflicts. Usually, the first PR to be ready gets merged, and others rebase.
Q: Can I propose a big feature that changes the architecture? A: Yes! But start with a proposal/design document first to discuss before implementing.
Q: What happens if my PR is rejected? A: Don't take it personally! We'll explain why and suggest alternatives. Many great contributions start as rejected PRs that get improved.
- Bugs: Create issue with bug report template
- Features: Create issue with feature request template
- Questions: Use Discussions instead
- Q&A: Ask questions about contributing
- Ideas: Discuss new features
- Show and Tell: Share your contributions
For sensitive issues (security, private matters), email the maintainer directly.
- Use welcoming and inclusive language
- Be respectful of differing viewpoints
- Gracefully accept constructive criticism
- Remember maintainers are volunteers
- Response times may vary
- Complex issues take time to resolve
- Help others when you can
- Share your knowledge
- Welcome new contributors
- Fix a typo in documentation
- Improve a comment in the code
- Add an example to the README
- Report a small bug you found
- Test on a new platform and report results
- Add a new icon to the icon sets
- Improve an error message
- Write a test for an untested function
- Add a usage example to docstring
- Improve the help text
- Add a new search engine
- Implement a small feature
- Fix a documented bug
- Write a guide for the wiki
- Improve performance of a function
# 1. Fork and clone
git clone https://github.com/YOUR_USERNAME/NaviDuck.git
cd NaviDuck
# 2. Fix a simple typo (find one in naviduck.py)
# Example: Change "seach" to "search" on line 123
# 3. Commit
git add naviduck.py
git commit -m "docs: fix typo in search function"
# 4. Push
git push origin main
# 5. Create PR on GitHub
# Done! You're now a contributor! 🎉We track and celebrate contributions:
| Metric | Goal | Current |
|---|---|---|
| Contributors | 50+ | [Number] |
| PRs Merged | 100+ | [Number] |
| Issues Closed | 200+ | [Number] |
| Test Coverage | 80%+ | [Percentage] |
| Documentation | Complete | [Status] |
- Browse open issues: Look for "good first issue" or "help wanted"
- Join the discussion: Comment on issues you're interested in
- Set up your environment: Follow the development setup guide
- Start small: Make your first contribution today!
- Every contribution matters, no matter how small
- The community is here to help you
- Your work will help users around the world
- You're joining a project that values privacy, usability, and open source
Last updated: 12/22/2025
Contributing Guide version: 3.0
Thank you for considering contributing to NaviDuck! Your help makes this project better for everyone. 🦆✨