Quickstart: Modular Code Refactoring
Path: kitty-specs/004-modular-code-refactoring/quickstart.md
Overview
This guide helps developers work on the modular refactoring of spec-kitty's monolithic files. The refactoring splits 5,730 lines across two files into ~21 modules, enabling parallel development by multiple agents.
Prerequisites
- Python 3.11+
- Git with worktree support
- spec-kitty development environment set up
- Access to the
004-modular-code-refactoringbranch
Getting Started
1. Set Up Your Worktree
# From main spec-kitty repo
git worktree add .worktrees/004-modular-code-refactoring 004-modular-code-refactoring
cd .worktrees/004-modular-code-refactoring
2. Understand Your Agent Assignment
Check which agent role you've been assigned:
- Foundation Agent: Creates core modules (Day 1)
- Agent A: Dashboard Infrastructure (Days 2-3)
- Agent B: Template System (Days 2-3)
- Agent C: Core Services (Days 2-3)
- Agent D: Dashboard Handlers (Days 4-5)
- Agent E: CLI Commands (Days 4-5)
- Agent F: GitHub & Init (Days 4-5)
3. Review Your Files
Each agent owns specific files exclusively:
# Example for Agent A
dashboard/static/dashboard.css
dashboard/static/dashboard.js
dashboard/templates/index.html
dashboard/scanner.py
dashboard/diagnostics.py
Development Workflow
Step 1: Create Your Module Structure
# Example for Agent A
mkdir -p src/specify_cli/dashboard/static
mkdir -p src/specify_cli/dashboard/templates
touch src/specify_cli/dashboard/__init__.py
touch src/specify_cli/dashboard/scanner.py
touch src/specify_cli/dashboard/diagnostics.py
Step 2: Extract Code from Monolith
1. Open the source file (__init__.py or dashboard.py) 2. Locate your assigned functions/classes 3. Copy to your new module 4. Add necessary imports
Example extraction:
# From dashboard.py lines 381-441 → scanner.py
def scan_all_features(project_root: Path) -> list[dict]:
"""Scan all features in project."""
# ... extracted code ...
Step 3: Create Import Stubs
For modules not yet created by other agents:
# In your module
try:
from ..core.config import AI_CHOICES # Will exist after Foundation Agent
except ImportError:
# Stub for development
AI_CHOICES = {}
Step 4: Define Your Interface
Document your module's public API:
# In dashboard/scanner.py
__all__ = ['scan_all_features', 'scan_feature_kanban', 'get_feature_artifacts']
def scan_all_features(project_root: Path) -> list[dict]:
"""
Scan all features in project.
Args:
project_root: Path to project root containing .kittify
Returns:
List of feature dictionaries with id, name, status, etc.
"""
pass # Implementation here
Step 5: Write Tests
Create corresponding test file:
# tests/test_dashboard/test_scanner.py
import pytest
from pathlib import Path
from specify_cli.dashboard.scanner import scan_all_features
def test_scan_all_features(mock_project_root):
features = scan_all_features(mock_project_root)
assert isinstance(features, list)
# ... more assertions ...
Coordination Rules
1. No Concurrent Edits
- Each file is owned by ONE agent only
- Check file ownership before editing
- Never edit another agent's files
2. Daily Sync
At end of each day:
git add .
git commit -m "Agent A: Extracted dashboard infrastructure modules"
git push
3. Import Dependencies
When depending on another agent's module:
# Option 1: Stub for development
try:
from ..template.manager import copy_base
except ImportError:
def copy_base(*args, **kwargs):
raise NotImplementedError("Waiting for Agent B")
# Option 2: Wait for dependency
# Only work on modules after dependencies are complete
4. Testing Strategy
Run tests for your modules:
# Test just your modules
pytest tests/test_dashboard/test_scanner.py -v
# Integration test after merge
pytest tests/ -v
Module Guidelines
Size Constraints
- Maximum 200 lines per module (excluding comments/docstrings)
- If approaching limit, split into sub-modules
Import Compatibility
Handle three contexts:
# At top of module
try:
# Standard package import
from .scanner import scan_all_features
except ImportError:
try:
# Subprocess/detached context
from specify_cli.dashboard.scanner import scan_all_features
except ImportError:
# Development context
import sys
sys.path.insert(0, str(Path(__file__).parent.parent))
from dashboard.scanner import scan_all_features
Documentation
Every module needs:
- Module docstring explaining purpose
- Function docstrings with args/returns
- Type hints for public functions
__all__list of public exports
Common Patterns
Pattern 1: Extracting Classes
# Original in __init__.py
class StepTracker:
def __init__(self): ...
def add(self): ...
# ... 100+ lines ...
# Extract to cli/ui.py
from dataclasses import dataclass, field
from typing import Literal
from rich.tree import Tree
@dataclass
class StepInfo:
label: str
status: Literal["pending", "running", "complete", "error", "skipped"]
# ...
class StepTracker:
# ... implementation ...
Pattern 2: Extracting Constants
# Original scattered throughout __init__.py
AI_CHOICES = {...}
MISSION_CHOICES = {...}
# Consolidate in core/config.py
"""Configuration constants for spec-kitty."""
AI_CHOICES = {
"codex": "Codex CLI",
"claude": "Claude Code",
# ...
}
MISSION_CHOICES = {
"software-dev": "Software Dev Kitty",
# ...
}
Pattern 3: Extracting HTML/CSS/JS
# Original in dashboard.py
def get_dashboard_html():
return '''<!DOCTYPE html>
<html>
<!-- 1000+ lines of HTML/CSS/JS -->
</html>'''
# Extract to dashboard/templates/index.html
<!DOCTYPE html>
<html>
<!-- Actual HTML -->
</html>
# And dashboard/handlers/base.py
def get_dashboard_html():
template_path = Path(__file__).parent.parent / "templates" / "index.html"
return template_path.read_text()
Troubleshooting
Issue: Import Not Found
# If seeing: ImportError: cannot import name 'X' from 'Y'
# Add fallback import:
try:
from ..core.config import X
except ImportError:
X = None # or appropriate default
Issue: Circular Import
# Avoid by using TYPE_CHECKING
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ..other.module import SomeClass
def my_function(obj: 'SomeClass'):
# Use string annotation to avoid runtime import
pass
Issue: Test Failures
# Run with verbose output
pytest tests/test_my_module.py -vvs
# Check import paths
python -c "from specify_cli.my_package.my_module import my_function"
Checklist
Before marking your modules complete:
- □ All modules under 200 lines
- □ All public functions have docstrings
- □ Type hints added for public API
- □ Tests written and passing
- □ Import compatibility handled
- □ No references to old monolithic imports
- □ Code formatted with black/ruff
- □ Integration tested with other agents' modules
Resources
- Full Specification
- Implementation Plan
- Data Model
- Module Interfaces
- Research Findings
Support
If blocked or need clarification: 1. Check the module ownership matrix in plan.md 2. Coordinate with other agents via git commits 3. Use stub implementations to continue development 4. Document blockers in your commit messages