527 lines
12 KiB
Markdown
527 lines
12 KiB
Markdown
# Contributing to ComfyUI-KikoTools
|
|
|
|
We love contributions! ComfyUI-KikoTools is built by the community, for the community. This guide will help you get started with contributing to our collection of essential ComfyUI tools.
|
|
|
|
## 🌟 Ways to Contribute
|
|
|
|
### 🐛 Bug Reports
|
|
|
|
- Found a bug? Please [open an issue](https://github.com/ComfyAssets/ComfyUI-KikoTools/issues)
|
|
- Include ComfyUI version, tool name, and reproduction steps
|
|
- Screenshots and error logs are super helpful!
|
|
|
|
### 💡 Feature Requests
|
|
|
|
- Have an idea for a new tool? [Start a discussion](https://github.com/ComfyAssets/ComfyUI-KikoTools/discussions)
|
|
- Describe the use case and expected behavior
|
|
- Check existing tools to avoid duplication
|
|
|
|
### 🔧 Code Contributions
|
|
|
|
- Fix bugs, improve performance, add new tools
|
|
- Follow our development principles (see below)
|
|
- All contributions must include tests
|
|
|
|
### 📚 Documentation
|
|
|
|
- Improve README, add examples, write tutorials
|
|
- Update tool documentation in `examples/documentation/`
|
|
- Create example workflows in `examples/workflows/`
|
|
|
|
## 🚀 Getting Started
|
|
|
|
### Prerequisites
|
|
|
|
- Python 3.8+
|
|
- ComfyUI installation (for testing)
|
|
- Git knowledge
|
|
- Basic understanding of PyTorch tensors
|
|
|
|
### Development Setup
|
|
|
|
1. **Fork and Clone**
|
|
|
|
```bash
|
|
git clone https://github.com/YOUR_USERNAME/ComfyUI-KikoTools.git
|
|
cd ComfyUI-KikoTools
|
|
```
|
|
|
|
2. **Create Virtual Environment**
|
|
|
|
```bash
|
|
python -m venv venv
|
|
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
```
|
|
|
|
3. **Install Dependencies**
|
|
|
|
```bash
|
|
pip install -r requirements-dev.txt
|
|
```
|
|
|
|
4. **Verify Setup**
|
|
|
|
```bash
|
|
python -c "
|
|
import sys, os
|
|
sys.path.insert(0, os.getcwd())
|
|
from kikotools.tools.resolution_calculator.node import ResolutionCalculatorNode
|
|
import torch
|
|
|
|
node = ResolutionCalculatorNode()
|
|
result = node.calculate_resolution(2.0, image=torch.randn(1, 512, 512, 3))
|
|
print(f'✅ Setup successful! Test result: {result[0]}x{result[1]}')
|
|
"
|
|
```
|
|
|
|
## 🏗️ Development Principles
|
|
|
|
We follow these principles to maintain high code quality:
|
|
|
|
### KISS (Keep It Simple, Stupid)
|
|
|
|
- Single responsibility per tool
|
|
- Simple, intuitive interfaces
|
|
- Minimal dependencies
|
|
|
|
### Separation of Concerns
|
|
|
|
```
|
|
tool_name/
|
|
├── logic.py # Pure functions, no ComfyUI dependencies
|
|
├── node.py # ComfyUI interface only
|
|
└── __init__.py # Module exports
|
|
```
|
|
|
|
### DRY (Don't Repeat Yourself)
|
|
|
|
- Shared functionality goes in `base/`
|
|
- Reusable utilities in `base/utils.py`
|
|
- Common validation patterns
|
|
|
|
### SOLID Principles
|
|
|
|
- **S**ingle Responsibility: Each class has one reason to change
|
|
- **O**pen/Closed: Open for extension, closed for modification
|
|
- **L**iskov Substitution: Subclasses are substitutable for base classes
|
|
- **I**nterface Segregation: Minimal, focused interfaces
|
|
- **D**ependency Inversion: Depend on abstractions, not concretions
|
|
|
|
## 🧪 Test-Driven Development (TDD)
|
|
|
|
We use TDD for all new features:
|
|
|
|
### 1. Write Tests First
|
|
|
|
```python
|
|
def test_new_feature_behavior():
|
|
"""Test what the feature should do before implementing it"""
|
|
# Arrange
|
|
input_data = create_test_input()
|
|
expected_output = calculate_expected_result()
|
|
|
|
# Act
|
|
actual_output = new_feature_function(input_data)
|
|
|
|
# Assert
|
|
assert actual_output == expected_output
|
|
```
|
|
|
|
### 2. Run Tests (Should Fail)
|
|
|
|
```bash
|
|
python -c "import sys; sys.path.insert(0, '.'); from tests.unit.test_new_feature import *; test_new_feature_behavior()"
|
|
```
|
|
|
|
### 3. Implement Minimal Code
|
|
|
|
Write just enough code to make the test pass.
|
|
|
|
### 4. Refactor and Expand
|
|
|
|
- Add error handling
|
|
- Optimize performance
|
|
- Add comprehensive validation
|
|
- Ensure divisible-by-8 constraints
|
|
|
|
### 5. Integration Testing
|
|
|
|
Test the complete workflow in a ComfyUI-like environment.
|
|
|
|
## 🛠️ Adding a New Tool
|
|
|
|
Follow this step-by-step process:
|
|
|
|
### Step 1: Planning
|
|
|
|
1. **Create Issue**: Describe the tool's purpose and requirements
|
|
2. **Update plan.md**: Add detailed specifications
|
|
3. **Design Interface**: Define inputs, outputs, and constraints
|
|
|
|
### Step 2: Project Structure
|
|
|
|
```bash
|
|
# Create tool directory
|
|
mkdir -p kikotools/tools/your_tool_name
|
|
|
|
# Create files
|
|
touch kikotools/tools/your_tool_name/__init__.py
|
|
touch kikotools/tools/your_tool_name/logic.py
|
|
touch kikotools/tools/your_tool_name/node.py
|
|
|
|
# Create tests
|
|
touch tests/unit/tools/test_your_tool_name.py
|
|
```
|
|
|
|
### Step 3: Write Tests (TDD)
|
|
|
|
```python
|
|
# tests/unit/tools/test_your_tool_name.py
|
|
import pytest
|
|
import torch
|
|
from kikotools.tools.your_tool_name.logic import your_main_function
|
|
from kikotools.tools.your_tool_name.node import YourToolNode
|
|
|
|
class TestYourToolLogic:
|
|
def test_basic_functionality(self):
|
|
# Test core logic here
|
|
pass
|
|
|
|
def test_error_handling(self):
|
|
# Test edge cases and errors
|
|
pass
|
|
|
|
class TestYourToolNode:
|
|
def test_comfyui_interface(self):
|
|
# Test ComfyUI integration
|
|
pass
|
|
```
|
|
|
|
### Step 4: Implement Logic
|
|
|
|
```python
|
|
# kikotools/tools/your_tool_name/logic.py
|
|
import torch
|
|
from typing import Tuple, Optional
|
|
|
|
def your_main_function(input_tensor: torch.Tensor, param: float) -> Tuple[int, int]:
|
|
"""
|
|
Pure function implementing the core logic
|
|
|
|
Args:
|
|
input_tensor: Input tensor from ComfyUI
|
|
param: Tool-specific parameter
|
|
|
|
Returns:
|
|
Tuple of results
|
|
|
|
Raises:
|
|
ValueError: If validation fails
|
|
"""
|
|
# Implement logic here
|
|
pass
|
|
```
|
|
|
|
### Step 5: Create ComfyUI Node
|
|
|
|
```python
|
|
# kikotools/tools/your_tool_name/node.py
|
|
from ...base import ComfyAssetsBaseNode
|
|
from .logic import your_main_function
|
|
|
|
class YourToolNode(ComfyAssetsBaseNode):
|
|
"""ComfyUI node for Your Tool"""
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"param": ("FLOAT", {"default": 1.0, "min": 0.1, "max": 10.0}),
|
|
},
|
|
"optional": {
|
|
"input_tensor": ("IMAGE",),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ("INT", "INT")
|
|
RETURN_NAMES = ("result1", "result2")
|
|
FUNCTION = "execute_tool"
|
|
|
|
def execute_tool(self, param, input_tensor=None):
|
|
try:
|
|
self.validate_inputs(param=param, input_tensor=input_tensor)
|
|
return your_main_function(input_tensor, param)
|
|
except Exception as e:
|
|
self.handle_error(f"Tool execution failed: {str(e)}", e)
|
|
```
|
|
|
|
### Step 6: Register Tool
|
|
|
|
```python
|
|
# kikotools/tools/your_tool_name/__init__.py
|
|
from .node import YourToolNode
|
|
__all__ = ["YourToolNode"]
|
|
|
|
# Update kikotools/__init__.py
|
|
from .tools.your_tool_name import YourToolNode
|
|
|
|
NODE_CLASS_MAPPINGS = {
|
|
"YourTool": YourToolNode,
|
|
}
|
|
|
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
"YourTool": "Your Tool Name",
|
|
}
|
|
```
|
|
|
|
### Step 7: Documentation
|
|
|
|
```markdown
|
|
# examples/documentation/your_tool_name.md
|
|
|
|
# Your Tool Name
|
|
|
|
## Overview
|
|
|
|
Brief description of what the tool does.
|
|
|
|
## Inputs
|
|
|
|
- param (FLOAT): Description of parameter
|
|
|
|
## Outputs
|
|
|
|
- result1 (INT): Description of first output
|
|
- result2 (INT): Description of second output
|
|
|
|
## Use Cases
|
|
|
|
1. Use case 1
|
|
2. Use case 2
|
|
|
|
## Examples
|
|
|
|
Example workflows and usage patterns.
|
|
```
|
|
|
|
### Step 8: Testing and Validation
|
|
|
|
```bash
|
|
# Run your tests
|
|
python -c "import sys; sys.path.insert(0, '.'); [run your test functions]"
|
|
|
|
# Test integration
|
|
python -c "from kikotools.tools.your_tool_name import YourToolNode; print('✅ Integration successful')"
|
|
|
|
# Code quality
|
|
black kikotools/tools/your_tool_name/
|
|
flake8 kikotools/tools/your_tool_name/
|
|
```
|
|
|
|
## 📋 Pull Request Process
|
|
|
|
### Before Submitting
|
|
|
|
- [ ] All tests pass locally
|
|
- [ ] Code follows our style guidelines
|
|
- [ ] Documentation is updated
|
|
- [ ] Example workflows included (if applicable)
|
|
|
|
### PR Template
|
|
|
|
```markdown
|
|
## Description
|
|
|
|
Brief description of changes.
|
|
|
|
## Type of Change
|
|
|
|
- [ ] Bug fix
|
|
- [ ] New tool
|
|
- [ ] Enhancement
|
|
- [ ] Documentation update
|
|
|
|
## Testing
|
|
|
|
- [ ] Unit tests added/updated
|
|
- [ ] Integration tests pass
|
|
- [ ] Manual testing completed
|
|
|
|
## Checklist
|
|
|
|
- [ ] Code follows project style
|
|
- [ ] Self-review completed
|
|
- [ ] Documentation updated
|
|
- [ ] No breaking changes (or clearly documented)
|
|
```
|
|
|
|
### Review Process
|
|
|
|
1. **Automated Checks**: CI runs tests and quality checks
|
|
2. **Code Review**: Maintainer reviews code and provides feedback
|
|
3. **Testing**: Manual testing in ComfyUI environment
|
|
4. **Merge**: After approval, changes are merged to main
|
|
|
|
## 🎨 Code Style Guidelines
|
|
|
|
### Python Style
|
|
|
|
- **Formatting**: Use `black` (line length: 127)
|
|
- **Linting**: Follow `flake8` guidelines
|
|
- **Type Hints**: Use type annotations for all functions
|
|
- **Docstrings**: Google-style docstrings for all public functions
|
|
|
|
### Example Code Style
|
|
|
|
```python
|
|
from typing import Tuple, Optional
|
|
import torch
|
|
|
|
def calculate_dimensions(
|
|
input_tensor: torch.Tensor,
|
|
scale_factor: float
|
|
) -> Tuple[int, int]:
|
|
"""
|
|
Calculate scaled dimensions from input tensor.
|
|
|
|
Args:
|
|
input_tensor: Input image or latent tensor
|
|
scale_factor: Scaling factor to apply
|
|
|
|
Returns:
|
|
Tuple of (width, height) as integers
|
|
|
|
Raises:
|
|
ValueError: If input validation fails
|
|
"""
|
|
if scale_factor <= 0:
|
|
raise ValueError(f"Scale factor must be positive, got {scale_factor}")
|
|
|
|
# Implementation here
|
|
return width, height
|
|
```
|
|
|
|
### File Organization
|
|
|
|
```python
|
|
# Standard library imports
|
|
import os
|
|
import sys
|
|
from typing import Tuple, Optional
|
|
|
|
# Third-party imports
|
|
import torch
|
|
import numpy as np
|
|
|
|
# Local imports
|
|
from ...base import ComfyAssetsBaseNode
|
|
from .logic import helper_function
|
|
```
|
|
|
|
## 🐛 Debugging Guidelines
|
|
|
|
### Common Issues
|
|
|
|
1. **Import Errors**: Check `sys.path` and relative imports
|
|
2. **Tensor Shape Issues**: Validate input tensor dimensions
|
|
3. **ComfyUI Integration**: Ensure proper INPUT_TYPES format
|
|
4. **Memory Issues**: Test with various image sizes
|
|
|
|
### Debugging Tools
|
|
|
|
```python
|
|
# Debug tensor shapes
|
|
print(f"Tensor shape: {tensor.shape}")
|
|
print(f"Tensor dtype: {tensor.dtype}")
|
|
|
|
# Debug ComfyUI interface
|
|
input_types = YourNode.INPUT_TYPES()
|
|
print(f"Input types: {input_types}")
|
|
|
|
# Debug calculations
|
|
result = your_function(test_input)
|
|
print(f"Result: {result}, type: {type(result)}")
|
|
```
|
|
|
|
## 📊 Performance Guidelines
|
|
|
|
### Optimization Priorities
|
|
|
|
1. **Correctness**: Always prioritize correct results
|
|
2. **Memory Efficiency**: Minimize tensor copying
|
|
3. **Speed**: Optimize hot paths
|
|
4. **Compatibility**: Support various tensor sizes
|
|
|
|
### Performance Testing
|
|
|
|
```python
|
|
import time
|
|
import torch
|
|
|
|
def benchmark_function():
|
|
large_tensor = torch.randn(1, 2048, 2048, 3)
|
|
|
|
start_time = time.time()
|
|
result = your_function(large_tensor)
|
|
end_time = time.time()
|
|
|
|
print(f"Processing time: {end_time - start_time:.3f}s")
|
|
print(f"Memory usage: {torch.cuda.memory_allocated() / 1024**2:.1f}MB")
|
|
```
|
|
|
|
## 🤝 Community Guidelines
|
|
|
|
### Be Respectful
|
|
|
|
- Use welcoming and inclusive language
|
|
- Respect different viewpoints and experiences
|
|
- Focus on what's best for the community
|
|
|
|
### Be Constructive
|
|
|
|
- Provide helpful feedback in reviews
|
|
- Suggest improvements rather than just pointing out problems
|
|
- Help others learn and grow
|
|
|
|
### Be Patient
|
|
|
|
- Maintainers are volunteers with limited time
|
|
- New contributors may need extra guidance
|
|
- Complex features take time to implement properly
|
|
|
|
## ❓ Getting Help
|
|
|
|
### Documentation
|
|
|
|
- **README.md**: Project overview and quick start
|
|
- **examples/documentation/**: Tool-specific documentation
|
|
|
|
### Community
|
|
|
|
- **GitHub Issues**: Bug reports and feature requests
|
|
- **GitHub Discussions**: General questions and ideas
|
|
- **ComfyUI Discord**: Community chat (mention our tools)
|
|
|
|
### Maintainers
|
|
|
|
- Review pull requests and issues
|
|
- Provide guidance on architecture decisions
|
|
- Help with complex technical problems
|
|
|
|
## 🎉 Recognition
|
|
|
|
Contributors are recognized in several ways:
|
|
|
|
- **README.md**: Listed in contributors section
|
|
- **Release Notes**: Mentioned in relevant releases
|
|
- **GitHub**: Automatic contribution tracking
|
|
- **Community**: Recognition in ComfyUI community
|
|
|
|
## 📄 License
|
|
|
|
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
|
|
---
|
|
|
|
Thank you for contributing to ComfyUI-KikoTools! Together, we're building essential tools that make ComfyUI workflows more powerful and efficient. 🚀
|