Thank you for your interest in contributing to Keyspace! This document provides guidelines and instructions for contributing.
- Bug Fixes: Fix issues reported by users
- Features: Add new attack types or functionality
- Performance: Optimize existing code
- Tests: Add or improve test coverage
- Fix typos and grammar
- Add examples and tutorials
- Improve clarity and organization
- Translate to other languages
- Answer questions in discussions
- Report bugs with detailed information
- Suggest new features
- Share the project with others
Click the "Fork" button on GitHub to create your own copy.
git clone https://github.com/tworjaga/keyspace.git
cd keyspace# Create virtual environment
python -m venv venv
# Activate it
# Windows:
venv\Scripts\activate
# Linux/macOS:
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
pip install -r requirements-dev.txtgit checkout -b feature/your-feature-name
# or
git checkout -b fix/issue-descriptionWe follow PEP 8 with some modifications:
# Use 4 spaces for indentation
# Maximum line length: 100 characters
# Use descriptive variable names
# Good
def calculate_attack_speed(attempts, elapsed_time):
if elapsed_time > 0:
return attempts / elapsed_time
return 0.0
# Bad
def calc(a, t):
return a/t if t>0 else 0Use type hints for function signatures:
from typing import Optional, List, Dict
def start_attack(
target: str,
attack_type: str,
wordlist_path: Optional[str] = None
) -> Dict[str, str]:
...Add docstrings to all functions:
def start_attack(target: str, attack_type: str) -> dict:
"""
Start a password cracking attack.
Args:
target: The target to attack (SSID, username, etc.)
attack_type: Type of attack to perform
Returns:
Dictionary containing attack_id and status
Raises:
ValueError: If attack_type is invalid
"""
...Write tests for new functionality:
# tests/test_new_feature.py
import pytest
from backend.new_feature import new_function
def test_new_function():
result = new_function("test_input")
assert result == "expected_output"Run tests before submitting:
pytest tests/ -v- Create attack module in
backend/attacks/:
# backend/attacks/my_attack.py
from .base import BaseAttack
class MyAttack(BaseAttack):
def __init__(self, config):
super().__init__(config)
self.name = "My Custom Attack"
def run(self):
# Implementation
pass
def stop(self):
# Cleanup
pass- Register in attack factory:
# backend/attack_factory.py
from .attacks.my_attack import MyAttack
ATTACK_TYPES = {
# ... existing types
"My Attack": MyAttack,
}- Add tests:
# tests/attacks/test_my_attack.py
def test_my_attack():
attack = MyAttack({"target": "test"})
assert attack.name == "My Custom Attack"- Update documentation:
# USER_GUIDE.md
## My Attack
Description of how to use the new attack type...- Create UI component in
frontend/ui/:
# frontend/ui/my_panel.py
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel
class MyPanel(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.init_ui()
def init_ui(self):
layout = QVBoxLayout(self)
layout.addWidget(QLabel("My Panel"))- Integrate into main window:
# frontend/ui/main_window.py
from .my_panel import MyPanel
# In init_ui():
self.my_panel = MyPanel()
self.tab_widget.addTab(self.my_panel, "My Panel")- Edit relevant
.mdfiles - Follow Markdown best practices
- Add code examples where helpful
- Test all links
- Code follows style guidelines
- All tests pass
- New features have tests
- Documentation is updated
- Commit messages are clear
type: Brief description (50 chars or less)
More detailed explanation if needed. Wrap at 72 characters.
Include motivation for change and contrast with previous behavior.
- Bullet points are okay
- Use present tense: "Add feature" not "Added feature"
Types:
feat: New featurefix: Bug fixdocs: Documentation onlystyle: Code style (formatting)refactor: Code refactoringtest: Adding testschore: Maintenance tasks
Examples:
feat: Add mask attack support
Implement mask attack type similar to Hashcat syntax.
Supports ?l, ?u, ?d, ?s placeholders.
Closes #123
fix: Correct speed calculation in progress updates
Speed was being calculated incorrectly when attack was paused.
Now properly tracks only active time.
Fixes #456
- Search existing issues
- Check if it's already fixed in latest version
- Try to reproduce with minimal steps
**Description**
Clear description of the bug
**To Reproduce**
1. Step 1
2. Step 2
3. Step 3
**Expected Behavior**
What should happen
**Actual Behavior**
What actually happens
**Environment**
- OS: [e.g., Windows 11]
- Python: [e.g., 3.10.4]
- Version: [e.g., 1.0.0]
**Screenshots**
If applicable
**Additional Context**
Any other relevant information**Is your feature request related to a problem?**
Description of what the problem is
**Describe the solution you'd like**
Clear description of desired feature
**Describe alternatives you've considered**
Other approaches you've thought about
**Additional context**
Any other informationWe use labels to categorize issues:
bug: Something isn't workingenhancement: New feature requestdocumentation: Documentation improvementsgood first issue: Good for newcomershelp wanted: Extra attention neededperformance: Performance-relatedsecurity: Security-related
- Create PR from your fork to main repository
- Fill out PR template with all required information
- Link related issues using
Fixes #123orCloses #456 - Wait for review - maintainers will review within 1-2 days
- Address feedback - make requested changes
- Merge - once approved, maintainers will merge
- Branch is up to date with main
- Tests pass locally
- Code follows style guidelines
- Documentation updated
- CHANGELOG.md updated
- No merge conflicts
DO NOT create public issues for security vulnerabilities.
Instead:
- Email: security@keyspace.example.com
- Or use GitHub Security Advisories
See SECURITY.md for details.
- Never commit API keys or passwords
- Validate all user inputs
- Use parameterized queries
- Keep dependencies updated
- Follow OWASP guidelines
Look for issues labeled:
good first issuehelp wanteddocumentation
- Join our Discord
- Ask in GitHub Discussions
- Email: contributors@keyspace.example.com
Contributors will be:
- Listed in CONTRIBUTORS.md
- Mentioned in release notes
- Credited in the application About dialog
By contributing, you agree that your contributions will be licensed under the MIT License.
Questions about contributing? → GitHub Discussions
Ready to contribute? → Fork the Repository
Thank you for helping make Keyspace better!