chiron 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +57 -24
 - data/Gemfile.lock +1 -1
 - data/README.md +51 -8
 - data/lib/chiron/cli.rb +144 -20
 - data/lib/chiron/project_config.rb +95 -0
 - data/lib/chiron/templates/python/CLAUDE.md.erb +192 -0
 - data/lib/chiron/templates/python/commands/conventions/python.md +330 -0
 - data/lib/chiron/version.rb +1 -1
 - data/lib/chiron.rb +1 -0
 - metadata +21 -18
 - /data/lib/chiron/templates/{CLAUDE.md.erb → rails/CLAUDE.md.erb} +0 -0
 - /data/lib/chiron/templates/{commands → rails/commands}/conventions/rails.md +0 -0
 - /data/lib/chiron/templates/{claude → shared/claude}/settings.json +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/context/catchup.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/context/prime.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/context/quickstart.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/journal/instructions.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/journal/template.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/quality/pre-commit.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/quality/test-driven.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/workflows/create-prd.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/workflows/feature-complete.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/workflows/generate-tasks.md +0 -0
 - /data/lib/chiron/templates/{commands → shared/commands}/workflows/process-tasks.md +0 -0
 - /data/lib/chiron/templates/{development_journal.md.erb → shared/development_journal.md.erb} +0 -0
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: ee3cb5e4893ff687265d9e2d8d2fc75de956dd3abeca8b330e7f7c5f5d6c437a
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 0d53f562161301fa0093939a2eee2a3fa64c5f2a5a2c9f2802ecd31be12038f9
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: '0183d1aa5e2fe30cd565e96ab8680b8cdb8c29066391942c641f2038c3ce0394f6ae6fd03c008ce211fc599b7e3773a429b48fb70115eaa268dd5b5942e27ae4'
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: d7a016612648121ed2c031a0180c76637684285bc448f179d81850c8f85800a98964d346363e89d49d41c232d2c4a90f1178ff4606404478b85f06e99e60dafc
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -5,30 +5,63 @@ All notable changes to this project will be documented in this file. 
     | 
|
| 
       5 
5 
     | 
    
         
             
            The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
         
     | 
| 
       6 
6 
     | 
    
         
             
            and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            ## [ 
     | 
| 
      
 8 
     | 
    
         
            +
            ## [0.2.0] - 2025-07-01
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
            ### Added
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            #### Python Project Support
         
     | 
| 
      
 13 
     | 
    
         
            +
            - **Auto-detection**: Automatically detects Python projects via `requirements.txt`, `pyproject.toml`, `setup.py`, or `Pipfile`
         
     | 
| 
      
 14 
     | 
    
         
            +
            - **Framework Detection**: Identifies Django, FastAPI, Flask, or generic Python projects
         
     | 
| 
      
 15 
     | 
    
         
            +
            - **Python-specific CLAUDE.md template**: Customized for Python development with framework-specific sections
         
     | 
| 
      
 16 
     | 
    
         
            +
            - **CLI Options**: Added `--type=python`, `--with-django`, and `--with-fastapi` flags
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            #### Python Workflow Templates
         
     | 
| 
      
 19 
     | 
    
         
            +
            - **Python Conventions** (`python/commands/conventions/python.md`): Comprehensive Python best practices including PEP 8, type hints, async patterns, and framework-specific guidelines
         
     | 
| 
      
 20 
     | 
    
         
            +
            - **Python Testing** (`python/commands/quality/python-testing.md`): Complete pytest patterns, fixtures, mocking, async testing, and CI/CD
         
     | 
| 
      
 21 
     | 
    
         
            +
            - **Python Debugging** (`python/commands/workflows/debug-python.md`): Systematic debugging with pdb, logging, and performance profiling
         
     | 
| 
      
 22 
     | 
    
         
            +
            - **Python Refactoring** (`python/commands/workflows/python-refactor.md`): SOLID principles, design patterns, and code organization
         
     | 
| 
      
 23 
     | 
    
         
            +
            - **Flask Development** (`python/commands/workflows/flask-development.md`): Complete Flask application patterns, blueprints, forms, and testing
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            #### Enhanced Architecture
         
     | 
| 
      
 26 
     | 
    
         
            +
            - **ProjectConfig Class**: Language-agnostic configuration management for tools, commands, and package managers
         
     | 
| 
      
 27 
     | 
    
         
            +
            - **Template Organization**: Restructured templates with `rails/`, `python/`, and `shared/` directories
         
     | 
| 
      
 28 
     | 
    
         
            +
            - **Framework-specific Content**: Dynamic template content based on detected frameworks
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            #### Testing & Quality
         
     | 
| 
      
 31 
     | 
    
         
            +
            - **Comprehensive Test Suite**: 41 tests covering both Rails and Python functionality
         
     | 
| 
      
 32 
     | 
    
         
            +
            - **Framework Detection Tests**: Tests for Django, FastAPI, and Flask project detection
         
     | 
| 
      
 33 
     | 
    
         
            +
            - **ProjectConfig Tests**: Full coverage of configuration management
         
     | 
| 
      
 34 
     | 
    
         
            +
            - **Backward Compatibility**: All existing Rails functionality preserved
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            ### Enhanced
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            #### CLI Improvements
         
     | 
| 
      
 39 
     | 
    
         
            +
            - **Smart Project Detection**: Improved auto-detection with user prompts for unknown projects
         
     | 
| 
      
 40 
     | 
    
         
            +
            - **Project-specific Tips**: Displays relevant setup tips after initialization
         
     | 
| 
      
 41 
     | 
    
         
            +
            - **Doctor Command**: Enhanced health checks for both Rails and Python projects
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            #### Documentation
         
     | 
| 
      
 44 
     | 
    
         
            +
            - **README**: Updated with Python examples and framework-specific usage
         
     | 
| 
      
 45 
     | 
    
         
            +
            - **Template Structure**: Clear documentation of language-specific workflow organization
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            ### Technical Details
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            #### Supported Python Frameworks
         
     | 
| 
      
 50 
     | 
    
         
            +
            - **Django**: Detects `manage.py`, includes Django ORM patterns, management commands
         
     | 
| 
      
 51 
     | 
    
         
            +
            - **FastAPI**: Detects FastAPI in requirements, includes async patterns, API documentation
         
     | 
| 
      
 52 
     | 
    
         
            +
            - **Flask**: Detects Flask dependencies, includes blueprint patterns, forms, testing
         
     | 
| 
      
 53 
     | 
    
         
            +
            - **Generic Python**: Supports any Python project with standard tooling
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            #### Code Quality Tools
         
     | 
| 
      
 56 
     | 
    
         
            +
            - **Rails**: RuboCop, RSpec, Rails conventions
         
     | 
| 
      
 57 
     | 
    
         
            +
            - **Python**: Black, flake8, mypy, pytest, type hints
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            ## [0.1.0] - 2025-06-30
         
     | 
| 
       11 
60 
     | 
    
         | 
| 
       12 
61 
     | 
    
         
             
            ### Added
         
     | 
| 
       13 
     | 
    
         
            -
            - Initial release  
     | 
| 
       14 
     | 
    
         
            -
            -  
     | 
| 
       15 
     | 
    
         
            -
            - PRD  
     | 
| 
       16 
     | 
    
         
            -
            -  
     | 
| 
       17 
     | 
    
         
            -
            -  
     | 
| 
       18 
     | 
    
         
            -
            -  
     | 
| 
       19 
     | 
    
         
            -
            - Migration tool from `.cursor` to `.claude` directory structure
         
     | 
| 
       20 
     | 
    
         
            -
            - Comprehensive test suite with RSpec
         
     | 
| 
       21 
     | 
    
         
            -
            - GitHub Actions CI/CD pipeline
         
     | 
| 
       22 
     | 
    
         
            -
            - Support for Ruby 3.0+ and Rails projects
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            ### Features
         
     | 
| 
       25 
     | 
    
         
            -
            - **Quick Setup**: Initialize Claude workflow with one command
         
     | 
| 
       26 
     | 
    
         
            -
            - **PRD Workflow**: Structured Product Requirements Document creation
         
     | 
| 
       27 
     | 
    
         
            -
            - **Task Management**: Generate and track implementation tasks
         
     | 
| 
       28 
     | 
    
         
            -
            - **Development Journal**: Track progress and maintain project history
         
     | 
| 
       29 
     | 
    
         
            -
            - **Migration Tool**: Easy migration from `.cursor` to `.claude` structure
         
     | 
| 
       30 
     | 
    
         
            -
            - **Quality Checks**: Pre-commit checklists and TDD workflows
         
     | 
| 
       31 
     | 
    
         
            -
            - **Customizable**: Adapt workflows to your team's needs
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
            [Unreleased]: https://github.com/ebrett/chiron/compare/v0.1.0...HEAD
         
     | 
| 
       34 
     | 
    
         
            -
            [0.1.0]: https://github.com/ebrett/chiron/releases/tag/v0.1.0
         
     | 
| 
      
 62 
     | 
    
         
            +
            - Initial release with Rails project support
         
     | 
| 
      
 63 
     | 
    
         
            +
            - Claude workflow initialization
         
     | 
| 
      
 64 
     | 
    
         
            +
            - PRD and task management workflows
         
     | 
| 
      
 65 
     | 
    
         
            +
            - Development journal system
         
     | 
| 
      
 66 
     | 
    
         
            +
            - Migration from .cursor to .claude structure
         
     | 
| 
      
 67 
     | 
    
         
            +
            - Rails-specific conventions and patterns
         
     | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Chiron
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            A Ruby gem that initializes Claude AI development workflows, PRD templates, and journaling system for Rails projects. Named after the wise centaur who mentored heroes, Chiron helps you quickly set up a structured development process that integrates seamlessly with Claude Code.
         
     | 
| 
      
 3 
     | 
    
         
            +
            A Ruby gem that initializes Claude AI development workflows, PRD templates, and journaling system for Rails and Python projects. Named after the wise centaur who mentored heroes, Chiron helps you quickly set up a structured development process that integrates seamlessly with Claude Code.
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            ## Features
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
         @@ -34,15 +34,16 @@ gem install chiron 
     | 
|
| 
       34 
34 
     | 
    
         | 
| 
       35 
35 
     | 
    
         
             
            ### Initialize Claude Workflow
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
            In your Rails  
     | 
| 
      
 37 
     | 
    
         
            +
            In your project root (Rails or Python):
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
            ```bash
         
     | 
| 
       40 
40 
     | 
    
         
             
            chiron init
         
     | 
| 
       41 
41 
     | 
    
         
             
            ```
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
            This will:
         
     | 
| 
      
 44 
     | 
    
         
            +
            - Auto-detect your project type (Rails/Python)
         
     | 
| 
       44 
45 
     | 
    
         
             
            - Create `.claude/commands/` directory with workflow templates
         
     | 
| 
       45 
     | 
    
         
            -
            - Generate `CLAUDE.md` with  
     | 
| 
      
 46 
     | 
    
         
            +
            - Generate `CLAUDE.md` with language-specific configuration
         
     | 
| 
       46 
47 
     | 
    
         
             
            - Set up `tasks/` directory for PRDs and task lists
         
     | 
| 
       47 
48 
     | 
    
         
             
            - Initialize development journal in `docs/`
         
     | 
| 
       48 
49 
     | 
    
         
             
            - Update `.gitignore` appropriately
         
     | 
| 
         @@ -50,9 +51,13 @@ This will: 
     | 
|
| 
       50 
51 
     | 
    
         
             
            ### Command Options
         
     | 
| 
       51 
52 
     | 
    
         | 
| 
       52 
53 
     | 
    
         
             
            ```bash
         
     | 
| 
       53 
     | 
    
         
            -
            # Initialize with options
         
     | 
| 
      
 54 
     | 
    
         
            +
            # Initialize Rails project with options
         
     | 
| 
       54 
55 
     | 
    
         
             
            chiron init --project-name="MyApp" --with-viewcomponents
         
     | 
| 
       55 
56 
     | 
    
         | 
| 
      
 57 
     | 
    
         
            +
            # Initialize Python project with framework-specific patterns
         
     | 
| 
      
 58 
     | 
    
         
            +
            chiron init --type=python --with-django
         
     | 
| 
      
 59 
     | 
    
         
            +
            chiron init --type=python --with-fastapi
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
       56 
61 
     | 
    
         
             
            # Migrate from .cursor to .claude
         
     | 
| 
       57 
62 
     | 
    
         
             
            chiron migrate-cursor
         
     | 
| 
       58 
63 
     | 
    
         | 
| 
         @@ -71,15 +76,19 @@ chiron doctor 
     | 
|
| 
       71 
76 
     | 
    
         
             
            After initialization, you'll have:
         
     | 
| 
       72 
77 
     | 
    
         | 
| 
       73 
78 
     | 
    
         
             
            ```
         
     | 
| 
       74 
     | 
    
         
            -
            your- 
     | 
| 
      
 79 
     | 
    
         
            +
            your-project/
         
     | 
| 
       75 
80 
     | 
    
         
             
            ├── .claude/
         
     | 
| 
       76 
81 
     | 
    
         
             
            │   ├── commands/
         
     | 
| 
       77 
82 
     | 
    
         
             
            │   │   ├── workflows/      # Development workflows
         
     | 
| 
       78 
83 
     | 
    
         
             
            │   │   │   ├── create-prd.md
         
     | 
| 
       79 
84 
     | 
    
         
             
            │   │   │   ├── generate-tasks.md
         
     | 
| 
       80 
     | 
    
         
            -
            │   │   │    
     | 
| 
      
 85 
     | 
    
         
            +
            │   │   │   ├── process-tasks.md
         
     | 
| 
      
 86 
     | 
    
         
            +
            │   │   │   ├── debug-python.md    # Python debugging (Python projects)
         
     | 
| 
      
 87 
     | 
    
         
            +
            │   │   │   ├── python-refactor.md # Python refactoring (Python projects)
         
     | 
| 
      
 88 
     | 
    
         
            +
            │   │   │   └── flask-development.md # Flask patterns (Flask projects)
         
     | 
| 
       81 
89 
     | 
    
         
             
            │   │   ├── conventions/    # Language/framework rules
         
     | 
| 
       82 
     | 
    
         
            -
            │   │   │    
     | 
| 
      
 90 
     | 
    
         
            +
            │   │   │   ├── rails.md    # Rails-specific
         
     | 
| 
      
 91 
     | 
    
         
            +
            │   │   │   └── python.md   # Python-specific
         
     | 
| 
       83 
92 
     | 
    
         
             
            │   │   ├── context/        # Context commands
         
     | 
| 
       84 
93 
     | 
    
         
             
            │   │   │   ├── quickstart.md
         
     | 
| 
       85 
94 
     | 
    
         
             
            │   │   │   └── catchup.md
         
     | 
| 
         @@ -88,7 +97,8 @@ your-rails-app/ 
     | 
|
| 
       88 
97 
     | 
    
         
             
            │   │   │   └── template.md
         
     | 
| 
       89 
98 
     | 
    
         
             
            │   │   └── quality/        # Quality assurance
         
     | 
| 
       90 
99 
     | 
    
         
             
            │   │       ├── pre-commit.md
         
     | 
| 
       91 
     | 
    
         
            -
            │   │        
     | 
| 
      
 100 
     | 
    
         
            +
            │   │       ├── test-driven.md
         
     | 
| 
      
 101 
     | 
    
         
            +
            │   │       └── python-testing.md  # Python testing (Python projects)
         
     | 
| 
       92 
102 
     | 
    
         
             
            │   └── settings.json       # Claude permissions
         
     | 
| 
       93 
103 
     | 
    
         
             
            ├── CLAUDE.md              # Project-specific Claude instructions
         
     | 
| 
       94 
104 
     | 
    
         
             
            ├── tasks/                 # PRDs and task lists
         
     | 
| 
         @@ -133,6 +143,39 @@ After setup, you can tell Claude: 
     | 
|
| 
       133 
143 
     | 
    
         
             
            - "Update the journal"
         
     | 
| 
       134 
144 
     | 
    
         
             
            - "Run pre-commit checks"
         
     | 
| 
       135 
145 
     | 
    
         | 
| 
      
 146 
     | 
    
         
            +
            ### Language-Specific Commands
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            **Rails:**
         
     | 
| 
      
 149 
     | 
    
         
            +
            - "Run RuboCop on this file"
         
     | 
| 
      
 150 
     | 
    
         
            +
            - "Generate an RSpec test"
         
     | 
| 
      
 151 
     | 
    
         
            +
            - "Create a Rails migration"
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
            **Python:**
         
     | 
| 
      
 154 
     | 
    
         
            +
            - "Format this with Black"
         
     | 
| 
      
 155 
     | 
    
         
            +
            - "Create a pytest fixture"
         
     | 
| 
      
 156 
     | 
    
         
            +
            - "Generate a Django model"
         
     | 
| 
      
 157 
     | 
    
         
            +
            - "Debug this async function"
         
     | 
| 
      
 158 
     | 
    
         
            +
            - "Refactor this class using SOLID principles"
         
     | 
| 
      
 159 
     | 
    
         
            +
            - "Add type hints to this function"
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
            ## Supported Project Types
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
            ### Rails Projects
         
     | 
| 
      
 164 
     | 
    
         
            +
            - Full Rails conventions and best practices
         
     | 
| 
      
 165 
     | 
    
         
            +
            - RSpec testing patterns
         
     | 
| 
      
 166 
     | 
    
         
            +
            - Hotwire/Stimulus integration
         
     | 
| 
      
 167 
     | 
    
         
            +
            - ViewComponent support (optional)
         
     | 
| 
      
 168 
     | 
    
         
            +
            - RuboCop for code quality
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
            ### Python Projects
         
     | 
| 
      
 171 
     | 
    
         
            +
            - Auto-detects Django, FastAPI, Flask, or generic Python
         
     | 
| 
      
 172 
     | 
    
         
            +
            - pytest testing patterns with fixtures and parametrization
         
     | 
| 
      
 173 
     | 
    
         
            +
            - Black/flake8/mypy for code quality and type checking
         
     | 
| 
      
 174 
     | 
    
         
            +
            - Framework-specific templates (Django ORM, FastAPI async, Flask blueprints)
         
     | 
| 
      
 175 
     | 
    
         
            +
            - Debugging workflows with pdb and logging
         
     | 
| 
      
 176 
     | 
    
         
            +
            - Refactoring patterns and SOLID principles
         
     | 
| 
      
 177 
     | 
    
         
            +
            - Virtual environment and dependency management best practices
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
       136 
179 
     | 
    
         
             
            ## Customization
         
     | 
| 
       137 
180 
     | 
    
         | 
| 
       138 
181 
     | 
    
         
             
            All templates are customizable. After initialization:
         
     | 
    
        data/lib/chiron/cli.rb
    CHANGED
    
    | 
         @@ -13,18 +13,30 @@ module Chiron 
     | 
|
| 
       13 
13 
     | 
    
         
             
                  true
         
     | 
| 
       14 
14 
     | 
    
         
             
                end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                desc 'init', 'Initialize Claude workflow in current  
     | 
| 
      
 16 
     | 
    
         
            +
                desc 'init', 'Initialize Claude workflow in current project'
         
     | 
| 
       17 
17 
     | 
    
         
             
                option :project_name, type: :string, desc: 'Project name for CLAUDE.md'
         
     | 
| 
      
 18 
     | 
    
         
            +
                option :type, type: :string, desc: 'Project type (rails, python). Auto-detected if not specified'
         
     | 
| 
       18 
19 
     | 
    
         
             
                option :with_oauth, type: :boolean, default: false, desc: 'Include OAuth workflow examples'
         
     | 
| 
       19 
20 
     | 
    
         
             
                option :with_viewcomponents, type: :boolean, default: false, desc: 'Include ViewComponent rules'
         
     | 
| 
      
 21 
     | 
    
         
            +
                option :with_django, type: :boolean, default: false, desc: 'Include Django-specific patterns'
         
     | 
| 
      
 22 
     | 
    
         
            +
                option :with_fastapi, type: :boolean, default: false, desc: 'Include FastAPI-specific patterns'
         
     | 
| 
       20 
23 
     | 
    
         
             
                option :skip_journal, type: :boolean, default: false, desc: 'Skip development journal setup'
         
     | 
| 
       21 
24 
     | 
    
         
             
                def init
         
     | 
| 
       22 
     | 
    
         
            -
                  say '🤖 Initializing Claude  
     | 
| 
      
 25 
     | 
    
         
            +
                  say '🤖 Initializing Claude Setup...'.colorize(:blue)
         
     | 
| 
       23 
26 
     | 
    
         | 
| 
       24 
27 
     | 
    
         
             
                  @prompt = TTY::Prompt.new
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @project_type = determine_project_type
         
     | 
| 
       25 
29 
     | 
    
         
             
                  @project_name = options[:project_name] || prompt_for_project_name
         
     | 
| 
       26 
30 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                   
     | 
| 
      
 31 
     | 
    
         
            +
                  # Set up project configuration
         
     | 
| 
      
 32 
     | 
    
         
            +
                  if @project_type == :python
         
     | 
| 
      
 33 
     | 
    
         
            +
                    @python_framework = detect_python_framework
         
     | 
| 
      
 34 
     | 
    
         
            +
                    @config = ProjectConfig.new(@project_type, @python_framework)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  else
         
     | 
| 
      
 36 
     | 
    
         
            +
                    @config = ProjectConfig.new(@project_type)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  check_project_compatibility
         
     | 
| 
       28 
40 
     | 
    
         
             
                  create_directories
         
     | 
| 
       29 
41 
     | 
    
         
             
                  copy_templates
         
     | 
| 
       30 
42 
     | 
    
         
             
                  update_gitignore
         
     | 
| 
         @@ -34,6 +46,20 @@ module Chiron 
     | 
|
| 
       34 
46 
     | 
    
         
             
                  say '  1. Review and customize CLAUDE.md for your project'
         
     | 
| 
       35 
47 
     | 
    
         
             
                  say '  2. Check .claude/commands/ for available workflows'
         
     | 
| 
       36 
48 
     | 
    
         
             
                  say "  3. Run 'claude' to start using Claude with your new setup"
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  # Project-specific suggestions
         
     | 
| 
      
 51 
     | 
    
         
            +
                  case @project_type
         
     | 
| 
      
 52 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 53 
     | 
    
         
            +
                    say "\nPython project tips:".colorize(:yellow)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    say '  - Install dev dependencies: pip install pytest black flake8'
         
     | 
| 
      
 55 
     | 
    
         
            +
                    say '  - Set up pre-commit hooks for code quality'
         
     | 
| 
      
 56 
     | 
    
         
            +
                    say '  - Configure your IDE to use black formatting'
         
     | 
| 
      
 57 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 58 
     | 
    
         
            +
                    say "\nRails project tips:".colorize(:yellow)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    say '  - Ensure binstubs are set up: bundle binstubs bundler --force'
         
     | 
| 
      
 60 
     | 
    
         
            +
                    say "  - Run 'bin/rubocop' to check code style"
         
     | 
| 
      
 61 
     | 
    
         
            +
                    say "  - Use 'bin/rspec' for running tests"
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
       37 
63 
     | 
    
         
             
                end
         
     | 
| 
       38 
64 
     | 
    
         | 
| 
       39 
65 
     | 
    
         
             
                desc 'migrate-cursor', 'Migrate from .cursor to .claude structure'
         
     | 
| 
         @@ -90,8 +116,9 @@ module Chiron 
     | 
|
| 
       90 
116 
     | 
    
         
             
                def doctor
         
     | 
| 
       91 
117 
     | 
    
         
             
                  say '🏥 Running Claude setup diagnostics...'.colorize(:blue)
         
     | 
| 
       92 
118 
     | 
    
         | 
| 
      
 119 
     | 
    
         
            +
                  project_type = detect_project_type
         
     | 
| 
       93 
120 
     | 
    
         
             
                  checks = {
         
     | 
| 
       94 
     | 
    
         
            -
                     
     | 
| 
      
 121 
     | 
    
         
            +
                    "#{project_type.to_s.capitalize} project" => project_type != :unknown,
         
     | 
| 
       95 
122 
     | 
    
         
             
                    'CLAUDE.md exists' => File.exist?('CLAUDE.md'),
         
     | 
| 
       96 
123 
     | 
    
         
             
                    '.claude directory' => Dir.exist?('.claude'),
         
     | 
| 
       97 
124 
     | 
    
         
             
                    '.claude/commands' => Dir.exist?('.claude/commands'),
         
     | 
| 
         @@ -104,6 +131,15 @@ module Chiron 
     | 
|
| 
       104 
131 
     | 
    
         
             
                    end
         
     | 
| 
       105 
132 
     | 
    
         
             
                  }
         
     | 
| 
       106 
133 
     | 
    
         | 
| 
      
 134 
     | 
    
         
            +
                  # Add project-specific checks
         
     | 
| 
      
 135 
     | 
    
         
            +
                  case project_type
         
     | 
| 
      
 136 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 137 
     | 
    
         
            +
                    checks['Gemfile exists'] = File.exist?('Gemfile')
         
     | 
| 
      
 138 
     | 
    
         
            +
                    checks['Rails app structure'] = Dir.exist?('app')
         
     | 
| 
      
 139 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 140 
     | 
    
         
            +
                    checks['Python package file'] = python_package_exists?
         
     | 
| 
      
 141 
     | 
    
         
            +
                  end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
       107 
143 
     | 
    
         
             
                  checks.each do |check, result|
         
     | 
| 
       108 
144 
     | 
    
         
             
                    status = result ? '✅'.colorize(:green) : '❌'.colorize(:red)
         
     | 
| 
       109 
145 
     | 
    
         
             
                    say "#{status} #{check}"
         
     | 
| 
         @@ -112,7 +148,7 @@ module Chiron 
     | 
|
| 
       112 
148 
     | 
    
         
             
                  if checks.values.all?
         
     | 
| 
       113 
149 
     | 
    
         
             
                    say "\n✨ All checks passed!".colorize(:green)
         
     | 
| 
       114 
150 
     | 
    
         
             
                  else
         
     | 
| 
       115 
     | 
    
         
            -
                    say "\n⚠️  Some checks failed. Run ' 
     | 
| 
      
 151 
     | 
    
         
            +
                    say "\n⚠️  Some checks failed. Run 'chiron init' to fix.".colorize(:yellow)
         
     | 
| 
       116 
152 
     | 
    
         
             
                  end
         
     | 
| 
       117 
153 
     | 
    
         
             
                end
         
     | 
| 
       118 
154 
     | 
    
         | 
| 
         @@ -130,11 +166,58 @@ module Chiron 
     | 
|
| 
       130 
166 
     | 
    
         
             
                  end
         
     | 
| 
       131 
167 
     | 
    
         
             
                end
         
     | 
| 
       132 
168 
     | 
    
         | 
| 
       133 
     | 
    
         
            -
                def  
     | 
| 
       134 
     | 
    
         
            -
                  return  
     | 
| 
      
 169 
     | 
    
         
            +
                def determine_project_type
         
     | 
| 
      
 170 
     | 
    
         
            +
                  return options[:type].to_sym if options[:type]
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                  detected_type = detect_project_type
         
     | 
| 
      
 173 
     | 
    
         
            +
                  if detected_type == :unknown
         
     | 
| 
      
 174 
     | 
    
         
            +
                    @prompt.select('What type of project is this?') do |menu|
         
     | 
| 
      
 175 
     | 
    
         
            +
                      menu.choice 'Rails', :rails
         
     | 
| 
      
 176 
     | 
    
         
            +
                      menu.choice 'Python', :python
         
     | 
| 
      
 177 
     | 
    
         
            +
                    end
         
     | 
| 
      
 178 
     | 
    
         
            +
                  else
         
     | 
| 
      
 179 
     | 
    
         
            +
                    say "Detected #{detected_type} project".colorize(:green)
         
     | 
| 
      
 180 
     | 
    
         
            +
                    detected_type
         
     | 
| 
      
 181 
     | 
    
         
            +
                  end
         
     | 
| 
      
 182 
     | 
    
         
            +
                end
         
     | 
| 
       135 
183 
     | 
    
         | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
                   
     | 
| 
      
 184 
     | 
    
         
            +
                def detect_project_type
         
     | 
| 
      
 185 
     | 
    
         
            +
                  if File.exist?('Gemfile') && File.read('Gemfile').include?('rails')
         
     | 
| 
      
 186 
     | 
    
         
            +
                    :rails
         
     | 
| 
      
 187 
     | 
    
         
            +
                  elsif python_package_exists?
         
     | 
| 
      
 188 
     | 
    
         
            +
                    :python
         
     | 
| 
      
 189 
     | 
    
         
            +
                  else
         
     | 
| 
      
 190 
     | 
    
         
            +
                    :unknown
         
     | 
| 
      
 191 
     | 
    
         
            +
                  end
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                def detect_python_framework
         
     | 
| 
      
 195 
     | 
    
         
            +
                  if File.exist?('manage.py')
         
     | 
| 
      
 196 
     | 
    
         
            +
                    :django
         
     | 
| 
      
 197 
     | 
    
         
            +
                  elsif File.exist?('app.py') || File.exist?('main.py')
         
     | 
| 
      
 198 
     | 
    
         
            +
                    if File.exist?('requirements.txt')
         
     | 
| 
      
 199 
     | 
    
         
            +
                      content = File.read('requirements.txt')
         
     | 
| 
      
 200 
     | 
    
         
            +
                      return :fastapi if content.include?('fastapi')
         
     | 
| 
      
 201 
     | 
    
         
            +
                      return :flask if content.include?('flask')
         
     | 
| 
      
 202 
     | 
    
         
            +
                    end
         
     | 
| 
      
 203 
     | 
    
         
            +
                    :generic
         
     | 
| 
      
 204 
     | 
    
         
            +
                  else
         
     | 
| 
      
 205 
     | 
    
         
            +
                    :generic
         
     | 
| 
      
 206 
     | 
    
         
            +
                  end
         
     | 
| 
      
 207 
     | 
    
         
            +
                end
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                def check_project_compatibility
         
     | 
| 
      
 210 
     | 
    
         
            +
                  case @project_type
         
     | 
| 
      
 211 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 212 
     | 
    
         
            +
                    unless File.exist?('Gemfile')
         
     | 
| 
      
 213 
     | 
    
         
            +
                      error "This doesn't appear to be a Rails project!"
         
     | 
| 
      
 214 
     | 
    
         
            +
                      exit 1
         
     | 
| 
      
 215 
     | 
    
         
            +
                    end
         
     | 
| 
      
 216 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 217 
     | 
    
         
            +
                    if !python_package_exists? && @prompt.yes?('No Python package file found. Create requirements.txt?')
         
     | 
| 
      
 218 
     | 
    
         
            +
                      File.write('requirements.txt', "# Python dependencies\n")
         
     | 
| 
      
 219 
     | 
    
         
            +
                    end
         
     | 
| 
      
 220 
     | 
    
         
            +
                  end
         
     | 
| 
       138 
221 
     | 
    
         
             
                end
         
     | 
| 
       139 
222 
     | 
    
         | 
| 
       140 
223 
     | 
    
         
             
                def create_directories
         
     | 
| 
         @@ -157,8 +240,12 @@ module Chiron 
     | 
|
| 
       157 
240 
     | 
    
         
             
                def copy_templates(update: false)
         
     | 
| 
       158 
241 
     | 
    
         
             
                  # Copy CLAUDE.md template
         
     | 
| 
       159 
242 
     | 
    
         
             
                  unless update
         
     | 
| 
       160 
     | 
    
         
            -
                    template_path = File.join(templates_path, 'CLAUDE.md.erb')
         
     | 
| 
      
 243 
     | 
    
         
            +
                    template_path = File.join(templates_path, @project_type.to_s, 'CLAUDE.md.erb')
         
     | 
| 
      
 244 
     | 
    
         
            +
                    # Fall back to shared template if project-specific doesn't exist
         
     | 
| 
      
 245 
     | 
    
         
            +
                    template_path = File.join(templates_path, 'CLAUDE.md.erb') unless File.exist?(template_path)
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
       161 
247 
     | 
    
         
             
                    if File.exist?(template_path)
         
     | 
| 
      
 248 
     | 
    
         
            +
                      @python_framework = detect_python_framework if @project_type == :python
         
     | 
| 
       162 
249 
     | 
    
         
             
                      content = ERB.new(File.read(template_path)).result(binding)
         
     | 
| 
       163 
250 
     | 
    
         
             
                      File.write('CLAUDE.md', content)
         
     | 
| 
       164 
251 
     | 
    
         
             
                      say '📄 Created CLAUDE.md'.colorize(:light_blue)
         
     | 
| 
         @@ -169,7 +256,10 @@ module Chiron 
     | 
|
| 
       169 
256 
     | 
    
         
             
                  copy_commands
         
     | 
| 
       170 
257 
     | 
    
         | 
| 
       171 
258 
     | 
    
         
             
                  # Copy settings.json
         
     | 
| 
       172 
     | 
    
         
            -
                  settings_path = File.join(templates_path, 'claude 
     | 
| 
      
 259 
     | 
    
         
            +
                  settings_path = File.join(templates_path, 'shared', 'claude', 'settings.json')
         
     | 
| 
      
 260 
     | 
    
         
            +
                  # Fall back to root claude dir if shared doesn't exist
         
     | 
| 
      
 261 
     | 
    
         
            +
                  settings_path = File.join(templates_path, 'claude', 'settings.json') unless File.exist?(settings_path)
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
       173 
263 
     | 
    
         
             
                  if File.exist?(settings_path) && !File.exist?('.claude/settings.json')
         
     | 
| 
       174 
264 
     | 
    
         
             
                    FileUtils.cp(settings_path, '.claude/settings.json')
         
     | 
| 
       175 
265 
     | 
    
         
             
                    say '⚙️  Created .claude/settings.json'.colorize(:light_blue)
         
     | 
| 
         @@ -182,21 +272,50 @@ module Chiron 
     | 
|
| 
       182 
272 
     | 
    
         
             
                end
         
     | 
| 
       183 
273 
     | 
    
         | 
| 
       184 
274 
     | 
    
         
             
                def copy_commands
         
     | 
| 
       185 
     | 
    
         
            -
                   
     | 
| 
       186 
     | 
    
         
            -
                   
     | 
| 
      
 275 
     | 
    
         
            +
                  # Copy shared commands first
         
     | 
| 
      
 276 
     | 
    
         
            +
                  shared_commands_dir = File.join(templates_path, 'shared', 'commands')
         
     | 
| 
      
 277 
     | 
    
         
            +
                  if Dir.exist?(shared_commands_dir)
         
     | 
| 
      
 278 
     | 
    
         
            +
                    Dir.glob(File.join(shared_commands_dir, '**/*.md')).each do |file|
         
     | 
| 
      
 279 
     | 
    
         
            +
                      relative_path = file.sub("#{shared_commands_dir}/", '')
         
     | 
| 
      
 280 
     | 
    
         
            +
                      target_path = File.join('.claude/commands', relative_path)
         
     | 
| 
      
 281 
     | 
    
         
            +
             
     | 
| 
      
 282 
     | 
    
         
            +
                      FileUtils.mkdir_p(File.dirname(target_path))
         
     | 
| 
      
 283 
     | 
    
         
            +
                      FileUtils.cp(file, target_path)
         
     | 
| 
      
 284 
     | 
    
         
            +
                      say "📋 Copied shared: #{relative_path}".colorize(:light_blue)
         
     | 
| 
      
 285 
     | 
    
         
            +
                    end
         
     | 
| 
      
 286 
     | 
    
         
            +
                  end
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
                  # Copy project-specific commands
         
     | 
| 
      
 289 
     | 
    
         
            +
                  project_commands_dir = File.join(templates_path, @project_type.to_s, 'commands')
         
     | 
| 
      
 290 
     | 
    
         
            +
                  if Dir.exist?(project_commands_dir)
         
     | 
| 
      
 291 
     | 
    
         
            +
                    Dir.glob(File.join(project_commands_dir, '**/*.md')).each do |file|
         
     | 
| 
      
 292 
     | 
    
         
            +
                      relative_path = file.sub("#{project_commands_dir}/", '')
         
     | 
| 
      
 293 
     | 
    
         
            +
                      target_path = File.join('.claude/commands', relative_path)
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
                      FileUtils.mkdir_p(File.dirname(target_path))
         
     | 
| 
      
 296 
     | 
    
         
            +
                      FileUtils.cp(file, target_path)
         
     | 
| 
      
 297 
     | 
    
         
            +
                      say "📋 Copied #{@project_type}: #{relative_path}".colorize(:light_blue)
         
     | 
| 
      
 298 
     | 
    
         
            +
                    end
         
     | 
| 
      
 299 
     | 
    
         
            +
                  end
         
     | 
| 
       187 
300 
     | 
    
         | 
| 
       188 
     | 
    
         
            -
                   
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
             
     | 
| 
      
 301 
     | 
    
         
            +
                  # Fall back to legacy commands if new structure doesn't exist
         
     | 
| 
      
 302 
     | 
    
         
            +
                  legacy_commands_dir = File.join(templates_path, 'commands')
         
     | 
| 
      
 303 
     | 
    
         
            +
                  if !Dir.exist?(shared_commands_dir) && !Dir.exist?(project_commands_dir) && Dir.exist?(legacy_commands_dir)
         
     | 
| 
      
 304 
     | 
    
         
            +
                    Dir.glob(File.join(legacy_commands_dir, '**/*.md')).each do |file|
         
     | 
| 
      
 305 
     | 
    
         
            +
                      relative_path = file.sub("#{legacy_commands_dir}/", '')
         
     | 
| 
      
 306 
     | 
    
         
            +
                      target_path = File.join('.claude/commands', relative_path)
         
     | 
| 
       191 
307 
     | 
    
         | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
             
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
      
 308 
     | 
    
         
            +
                      FileUtils.mkdir_p(File.dirname(target_path))
         
     | 
| 
      
 309 
     | 
    
         
            +
                      FileUtils.cp(file, target_path)
         
     | 
| 
      
 310 
     | 
    
         
            +
                      say "📋 Copied #{relative_path}".colorize(:light_blue)
         
     | 
| 
      
 311 
     | 
    
         
            +
                    end
         
     | 
| 
       195 
312 
     | 
    
         
             
                  end
         
     | 
| 
       196 
313 
     | 
    
         
             
                end
         
     | 
| 
       197 
314 
     | 
    
         | 
| 
       198 
315 
     | 
    
         
             
                def create_development_journal
         
     | 
| 
       199 
     | 
    
         
            -
                  journal_template = File.join(templates_path, 'development_journal.md.erb')
         
     | 
| 
      
 316 
     | 
    
         
            +
                  journal_template = File.join(templates_path, 'shared', 'development_journal.md.erb')
         
     | 
| 
      
 317 
     | 
    
         
            +
                  # Fall back to root if shared doesn't exist
         
     | 
| 
      
 318 
     | 
    
         
            +
                  journal_template = File.join(templates_path, 'development_journal.md.erb') unless File.exist?(journal_template)
         
     | 
| 
       200 
319 
     | 
    
         
             
                  return unless File.exist?(journal_template)
         
     | 
| 
       201 
320 
     | 
    
         | 
| 
       202 
321 
     | 
    
         
             
                  content = ERB.new(File.read(journal_template)).result(binding)
         
     | 
| 
         @@ -252,6 +371,11 @@ module Chiron 
     | 
|
| 
       252 
371 
     | 
    
         
             
                  Chiron.templates_path
         
     | 
| 
       253 
372 
     | 
    
         
             
                end
         
     | 
| 
       254 
373 
     | 
    
         | 
| 
      
 374 
     | 
    
         
            +
                def python_package_exists?
         
     | 
| 
      
 375 
     | 
    
         
            +
                  File.exist?('requirements.txt') || File.exist?('pyproject.toml') ||
         
     | 
| 
      
 376 
     | 
    
         
            +
                    File.exist?('setup.py') || File.exist?('Pipfile')
         
     | 
| 
      
 377 
     | 
    
         
            +
                end
         
     | 
| 
      
 378 
     | 
    
         
            +
             
     | 
| 
       255 
379 
     | 
    
         
             
                def error(message)
         
     | 
| 
       256 
380 
     | 
    
         
             
                  say "❌ #{message}".colorize(:red)
         
     | 
| 
       257 
381 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,95 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Chiron
         
     | 
| 
      
 4 
     | 
    
         
            +
              class ProjectConfig
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :type, :test_runner, :linter, :formatter, :framework
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(project_type, framework = nil)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @type = project_type
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @framework = framework
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  case project_type
         
     | 
| 
      
 12 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @test_runner = 'bin/rspec'
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @linter = 'bin/rubocop'
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @formatter = 'bin/rubocop --autocorrect'
         
     | 
| 
      
 16 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @test_runner = 'pytest'
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @linter = 'flake8'
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @formatter = 'black'
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def framework_name
         
     | 
| 
      
 24 
     | 
    
         
            +
                  case @framework
         
     | 
| 
      
 25 
     | 
    
         
            +
                  when :django
         
     | 
| 
      
 26 
     | 
    
         
            +
                    'Django'
         
     | 
| 
      
 27 
     | 
    
         
            +
                  when :fastapi
         
     | 
| 
      
 28 
     | 
    
         
            +
                    'FastAPI'
         
     | 
| 
      
 29 
     | 
    
         
            +
                  when :flask
         
     | 
| 
      
 30 
     | 
    
         
            +
                    'Flask'
         
     | 
| 
      
 31 
     | 
    
         
            +
                  else
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @type.to_s.capitalize
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def test_command(file = nil)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  case @type
         
     | 
| 
      
 38 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 39 
     | 
    
         
            +
                    file ? "#{@test_runner} #{file}" : @test_runner
         
     | 
| 
      
 40 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 41 
     | 
    
         
            +
                    file ? "#{@test_runner} #{file}" : @test_runner
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def format_command(file = nil)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  case @type
         
     | 
| 
      
 47 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 48 
     | 
    
         
            +
                    file ? "#{@formatter} #{file}" : @formatter
         
     | 
| 
      
 49 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 50 
     | 
    
         
            +
                    file ? "#{@formatter} #{file}" : "#{@formatter} ."
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                def lint_command(file = nil)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  case @type
         
     | 
| 
      
 56 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 57 
     | 
    
         
            +
                    file ? "#{@linter} #{file}" : @linter
         
     | 
| 
      
 58 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 59 
     | 
    
         
            +
                    file ? "#{@linter} #{file}" : @linter
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                def package_file
         
     | 
| 
      
 64 
     | 
    
         
            +
                  case @type
         
     | 
| 
      
 65 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 66 
     | 
    
         
            +
                    'Gemfile'
         
     | 
| 
      
 67 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 68 
     | 
    
         
            +
                    if File.exist?('pyproject.toml')
         
     | 
| 
      
 69 
     | 
    
         
            +
                      'pyproject.toml'
         
     | 
| 
      
 70 
     | 
    
         
            +
                    elsif File.exist?('Pipfile')
         
     | 
| 
      
 71 
     | 
    
         
            +
                      'Pipfile'
         
     | 
| 
      
 72 
     | 
    
         
            +
                    elsif File.exist?('setup.py')
         
     | 
| 
      
 73 
     | 
    
         
            +
                      'setup.py'
         
     | 
| 
      
 74 
     | 
    
         
            +
                    else
         
     | 
| 
      
 75 
     | 
    
         
            +
                      'requirements.txt'
         
     | 
| 
      
 76 
     | 
    
         
            +
                    end
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def install_command
         
     | 
| 
      
 81 
     | 
    
         
            +
                  case @type
         
     | 
| 
      
 82 
     | 
    
         
            +
                  when :rails
         
     | 
| 
      
 83 
     | 
    
         
            +
                    'bundle install'
         
     | 
| 
      
 84 
     | 
    
         
            +
                  when :python
         
     | 
| 
      
 85 
     | 
    
         
            +
                    if File.exist?('Pipfile')
         
     | 
| 
      
 86 
     | 
    
         
            +
                      'pipenv install'
         
     | 
| 
      
 87 
     | 
    
         
            +
                    elsif File.exist?('pyproject.toml') && File.read('pyproject.toml').include?('[tool.poetry]')
         
     | 
| 
      
 88 
     | 
    
         
            +
                      'poetry install'
         
     | 
| 
      
 89 
     | 
    
         
            +
                    else
         
     | 
| 
      
 90 
     | 
    
         
            +
                      'pip install -r requirements.txt'
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,192 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # CLAUDE.md
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## Project Overview
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            <%= @project_name %> is a Python project<% if @python_framework == :django %> using Django framework<% elsif @python_framework == :fastapi %> using FastAPI framework<% elsif @python_framework == :flask %> using Flask framework<% end %>. [Add your project description here]
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ## Development Commands
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            **Important**: Use virtual environments for dependency isolation.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 14 
     | 
    
         
            +
            # Setup virtual environment
         
     | 
| 
      
 15 
     | 
    
         
            +
            python -m venv venv
         
     | 
| 
      
 16 
     | 
    
         
            +
            source venv/bin/activate  # On Windows: venv\Scripts\activate
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            # Install dependencies
         
     | 
| 
      
 19 
     | 
    
         
            +
            pip install -r requirements.txt
         
     | 
| 
      
 20 
     | 
    
         
            +
            <% if File.exist?('requirements-dev.txt') %>pip install -r requirements-dev.txt  # Development dependencies<% end %>
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            <% if @python_framework == :django %>
         
     | 
| 
      
 23 
     | 
    
         
            +
            # Django specific
         
     | 
| 
      
 24 
     | 
    
         
            +
            python manage.py migrate
         
     | 
| 
      
 25 
     | 
    
         
            +
            python manage.py runserver
         
     | 
| 
      
 26 
     | 
    
         
            +
            python manage.py test
         
     | 
| 
      
 27 
     | 
    
         
            +
            <% elsif @python_framework == :fastapi %>
         
     | 
| 
      
 28 
     | 
    
         
            +
            # FastAPI specific
         
     | 
| 
      
 29 
     | 
    
         
            +
            uvicorn main:app --reload  # Or app:app depending on your structure
         
     | 
| 
      
 30 
     | 
    
         
            +
            <% elsif @python_framework == :flask %>
         
     | 
| 
      
 31 
     | 
    
         
            +
            # Flask specific
         
     | 
| 
      
 32 
     | 
    
         
            +
            flask run  # Or python app.py
         
     | 
| 
      
 33 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            # Testing
         
     | 
| 
      
 36 
     | 
    
         
            +
            pytest                               # Run all tests
         
     | 
| 
      
 37 
     | 
    
         
            +
            pytest tests/                        # Run specific test directory
         
     | 
| 
      
 38 
     | 
    
         
            +
            pytest tests/test_models.py          # Run single test file
         
     | 
| 
      
 39 
     | 
    
         
            +
            pytest -v                           # Verbose output
         
     | 
| 
      
 40 
     | 
    
         
            +
            pytest --cov=.                      # With coverage
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            # Code quality
         
     | 
| 
      
 43 
     | 
    
         
            +
            black .                             # Format code
         
     | 
| 
      
 44 
     | 
    
         
            +
            flake8                              # Linting
         
     | 
| 
      
 45 
     | 
    
         
            +
            mypy .                              # Type checking (if configured)
         
     | 
| 
      
 46 
     | 
    
         
            +
            isort .                             # Sort imports
         
     | 
| 
      
 47 
     | 
    
         
            +
            ```
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            ## Architecture Overview
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            ### Project Structure
         
     | 
| 
      
 52 
     | 
    
         
            +
            [Document your main modules and their purposes]
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            ### Core Services/Modules
         
     | 
| 
      
 55 
     | 
    
         
            +
            [List your service classes/modules and their purposes]
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            <% if @python_framework == :django %>
         
     | 
| 
      
 58 
     | 
    
         
            +
            ### Models & Database
         
     | 
| 
      
 59 
     | 
    
         
            +
            [Describe your Django models and relationships]
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            ### Views & URLs
         
     | 
| 
      
 62 
     | 
    
         
            +
            [Describe your view organization and URL patterns]
         
     | 
| 
      
 63 
     | 
    
         
            +
            <% elsif @python_framework == :fastapi %>
         
     | 
| 
      
 64 
     | 
    
         
            +
            ### API Endpoints
         
     | 
| 
      
 65 
     | 
    
         
            +
            [Describe your API structure and main endpoints]
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            ### Schemas & Models
         
     | 
| 
      
 68 
     | 
    
         
            +
            [Describe your Pydantic models and database models]
         
     | 
| 
      
 69 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            ## Technical Stack
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            <% if @python_framework == :django %>
         
     | 
| 
      
 74 
     | 
    
         
            +
            - **Framework**: Django <%= options[:django_version] || "4.2+" %>
         
     | 
| 
      
 75 
     | 
    
         
            +
            - **Database**: PostgreSQL with Django ORM
         
     | 
| 
      
 76 
     | 
    
         
            +
            - **API**: Django REST Framework (if applicable)
         
     | 
| 
      
 77 
     | 
    
         
            +
            - **Frontend**: [Your frontend stack]
         
     | 
| 
      
 78 
     | 
    
         
            +
            <% elsif @python_framework == :fastapi %>
         
     | 
| 
      
 79 
     | 
    
         
            +
            - **Framework**: FastAPI
         
     | 
| 
      
 80 
     | 
    
         
            +
            - **Database**: [Your database] with SQLAlchemy/Tortoise-ORM
         
     | 
| 
      
 81 
     | 
    
         
            +
            - **API Documentation**: Automatic with Swagger/ReDoc
         
     | 
| 
      
 82 
     | 
    
         
            +
            - **Async Support**: Built-in async/await
         
     | 
| 
      
 83 
     | 
    
         
            +
            <% elsif @python_framework == :flask %>
         
     | 
| 
      
 84 
     | 
    
         
            +
            - **Framework**: Flask
         
     | 
| 
      
 85 
     | 
    
         
            +
            - **Database**: [Your database] with SQLAlchemy
         
     | 
| 
      
 86 
     | 
    
         
            +
            - **API**: Flask-RESTful (if applicable)
         
     | 
| 
      
 87 
     | 
    
         
            +
            <% else %>
         
     | 
| 
      
 88 
     | 
    
         
            +
            - **Language**: Python <%= `python --version 2>&1`.strip.split(' ')[1] rescue "3.x" %>
         
     | 
| 
      
 89 
     | 
    
         
            +
            - **Package Management**: pip/poetry/pipenv
         
     | 
| 
      
 90 
     | 
    
         
            +
            - **Testing**: pytest
         
     | 
| 
      
 91 
     | 
    
         
            +
            - **Code Quality**: black, flake8, mypy
         
     | 
| 
      
 92 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 93 
     | 
    
         
            +
            - **Testing**: pytest with fixtures
         
     | 
| 
      
 94 
     | 
    
         
            +
            - **Type Checking**: mypy (optional but recommended)
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            ## Environment Variables
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            Required for development:
         
     | 
| 
      
 99 
     | 
    
         
            +
            ```
         
     | 
| 
      
 100 
     | 
    
         
            +
            # Add your required environment variables here
         
     | 
| 
      
 101 
     | 
    
         
            +
            <% if @python_framework == :django %>
         
     | 
| 
      
 102 
     | 
    
         
            +
            SECRET_KEY=your-secret-key
         
     | 
| 
      
 103 
     | 
    
         
            +
            DEBUG=True
         
     | 
| 
      
 104 
     | 
    
         
            +
            DATABASE_URL=postgresql://user:pass@localhost/dbname
         
     | 
| 
      
 105 
     | 
    
         
            +
            <% elsif @python_framework == :fastapi %>
         
     | 
| 
      
 106 
     | 
    
         
            +
            DATABASE_URL=postgresql://user:pass@localhost/dbname
         
     | 
| 
      
 107 
     | 
    
         
            +
            JWT_SECRET=your-jwt-secret
         
     | 
| 
      
 108 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 109 
     | 
    
         
            +
            ```
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            ## Python Conventions
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            - Follow PEP 8 style guide
         
     | 
| 
      
 114 
     | 
    
         
            +
            - Use type hints where beneficial
         
     | 
| 
      
 115 
     | 
    
         
            +
            - Docstrings for all public functions/classes
         
     | 
| 
      
 116 
     | 
    
         
            +
            - Black for consistent formatting
         
     | 
| 
      
 117 
     | 
    
         
            +
            - Meaningful variable and function names
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            ## Development Patterns
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            ### Code Organization
         
     | 
| 
      
 122 
     | 
    
         
            +
            <% if @python_framework == :django %>
         
     | 
| 
      
 123 
     | 
    
         
            +
            - Follow Django's app-based architecture
         
     | 
| 
      
 124 
     | 
    
         
            +
            - Keep views thin, business logic in services/models
         
     | 
| 
      
 125 
     | 
    
         
            +
            - Use Django's built-in features (signals, middleware, etc.)
         
     | 
| 
      
 126 
     | 
    
         
            +
            <% elsif @python_framework == :fastapi %>
         
     | 
| 
      
 127 
     | 
    
         
            +
            - Organize routes by feature/domain
         
     | 
| 
      
 128 
     | 
    
         
            +
            - Use dependency injection
         
     | 
| 
      
 129 
     | 
    
         
            +
            - Leverage Pydantic for data validation
         
     | 
| 
      
 130 
     | 
    
         
            +
            - Keep endpoints focused and RESTful
         
     | 
| 
      
 131 
     | 
    
         
            +
            <% else %>
         
     | 
| 
      
 132 
     | 
    
         
            +
            - Organize code by feature/module
         
     | 
| 
      
 133 
     | 
    
         
            +
            - Use classes for complex state
         
     | 
| 
      
 134 
     | 
    
         
            +
            - Functions for simple transformations
         
     | 
| 
      
 135 
     | 
    
         
            +
            - Separate concerns clearly
         
     | 
| 
      
 136 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            ### PRD Workflow
         
     | 
| 
      
 139 
     | 
    
         
            +
            - Use `.claude/commands/workflows/create-prd.md` for structured feature development
         
     | 
| 
      
 140 
     | 
    
         
            +
            - PRDs should be saved in `/tasks/` directory as `prd-[feature-name].md`
         
     | 
| 
      
 141 
     | 
    
         
            +
            - Follow the clarifying questions process before implementation
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            ### Code Quality
         
     | 
| 
      
 144 
     | 
    
         
            +
            - Black for consistent formatting
         
     | 
| 
      
 145 
     | 
    
         
            +
            - Flake8 for linting
         
     | 
| 
      
 146 
     | 
    
         
            +
            - pytest for testing
         
     | 
| 
      
 147 
     | 
    
         
            +
            - Type hints with mypy (optional)
         
     | 
| 
      
 148 
     | 
    
         
            +
            - Comprehensive test coverage
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
            ## Testing Standards
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
            - Write tests before implementation (TDD)
         
     | 
| 
      
 153 
     | 
    
         
            +
            - Use pytest fixtures for test data
         
     | 
| 
      
 154 
     | 
    
         
            +
            - Mock external dependencies
         
     | 
| 
      
 155 
     | 
    
         
            +
            - Aim for high test coverage
         
     | 
| 
      
 156 
     | 
    
         
            +
            - Test edge cases and error conditions
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            <% if @python_framework == :django %>
         
     | 
| 
      
 159 
     | 
    
         
            +
            ### Django Testing
         
     | 
| 
      
 160 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 161 
     | 
    
         
            +
            from django.test import TestCase, Client
         
     | 
| 
      
 162 
     | 
    
         
            +
            from .models import MyModel
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
            class MyModelTestCase(TestCase):
         
     | 
| 
      
 165 
     | 
    
         
            +
                def setUp(self):
         
     | 
| 
      
 166 
     | 
    
         
            +
                    self.obj = MyModel.objects.create(name="Test")
         
     | 
| 
      
 167 
     | 
    
         
            +
                
         
     | 
| 
      
 168 
     | 
    
         
            +
                def test_string_representation(self):
         
     | 
| 
      
 169 
     | 
    
         
            +
                    self.assertEqual(str(self.obj), "Test")
         
     | 
| 
      
 170 
     | 
    
         
            +
            ```
         
     | 
| 
      
 171 
     | 
    
         
            +
            <% elsif @python_framework == :fastapi %>
         
     | 
| 
      
 172 
     | 
    
         
            +
            ### FastAPI Testing
         
     | 
| 
      
 173 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 174 
     | 
    
         
            +
            from fastapi.testclient import TestClient
         
     | 
| 
      
 175 
     | 
    
         
            +
            from main import app
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
            client = TestClient(app)
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
            def test_read_main():
         
     | 
| 
      
 180 
     | 
    
         
            +
                response = client.get("/")
         
     | 
| 
      
 181 
     | 
    
         
            +
                assert response.status_code == 200
         
     | 
| 
      
 182 
     | 
    
         
            +
            ```
         
     | 
| 
      
 183 
     | 
    
         
            +
            <% end %>
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            ## Important Reminders
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
            - Always run tests before committing
         
     | 
| 
      
 188 
     | 
    
         
            +
            - Use semantic commit messages
         
     | 
| 
      
 189 
     | 
    
         
            +
            - Update the development journal for significant changes
         
     | 
| 
      
 190 
     | 
    
         
            +
            - Follow the pre-commit checklist in `.claude/commands/quality/pre-commit.md`
         
     | 
| 
      
 191 
     | 
    
         
            +
            - Keep dependencies updated in requirements.txt
         
     | 
| 
      
 192 
     | 
    
         
            +
            - Document API changes
         
     | 
| 
         @@ -0,0 +1,330 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Python Development Conventions
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            You are an expert in Python, modern web frameworks (Django, FastAPI, Flask), and Python best practices.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## Code Style and Structure
         
     | 
| 
      
 6 
     | 
    
         
            +
            - Write clear, idiomatic Python code following PEP 8
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Use type hints to improve code clarity and catch errors early
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Prefer composition over inheritance
         
     | 
| 
      
 9 
     | 
    
         
            +
            - Keep functions small and focused (single responsibility)
         
     | 
| 
      
 10 
     | 
    
         
            +
            - Use descriptive names that convey intent
         
     | 
| 
      
 11 
     | 
    
         
            +
            - Structure code in logical modules and packages
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ## Naming Conventions
         
     | 
| 
      
 14 
     | 
    
         
            +
            - Use snake_case for functions, variables, and module names
         
     | 
| 
      
 15 
     | 
    
         
            +
            - Use PascalCase for class names
         
     | 
| 
      
 16 
     | 
    
         
            +
            - Use UPPER_SNAKE_CASE for constants
         
     | 
| 
      
 17 
     | 
    
         
            +
            - Prefix "private" attributes/methods with underscore (_)
         
     | 
| 
      
 18 
     | 
    
         
            +
            - Use descriptive names over comments when possible
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            ## Python Best Practices
         
     | 
| 
      
 21 
     | 
    
         
            +
            - Use Python 3.8+ features appropriately:
         
     | 
| 
      
 22 
     | 
    
         
            +
              - f-strings for formatting
         
     | 
| 
      
 23 
     | 
    
         
            +
              - Type hints and typing module
         
     | 
| 
      
 24 
     | 
    
         
            +
              - Dataclasses for simple data structures
         
     | 
| 
      
 25 
     | 
    
         
            +
              - Pattern matching (3.10+) where beneficial
         
     | 
| 
      
 26 
     | 
    
         
            +
            - List comprehensions for simple transformations
         
     | 
| 
      
 27 
     | 
    
         
            +
            - Generator expressions for memory efficiency
         
     | 
| 
      
 28 
     | 
    
         
            +
            - Context managers (with statements) for resource management
         
     | 
| 
      
 29 
     | 
    
         
            +
            - Pathlib over os.path for file operations
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ## Type Hints
         
     | 
| 
      
 32 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 33 
     | 
    
         
            +
            from typing import List, Dict, Optional, Union
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            def process_data(
         
     | 
| 
      
 36 
     | 
    
         
            +
                items: List[str], 
         
     | 
| 
      
 37 
     | 
    
         
            +
                config: Optional[Dict[str, Any]] = None
         
     | 
| 
      
 38 
     | 
    
         
            +
            ) -> Dict[str, int]:
         
     | 
| 
      
 39 
     | 
    
         
            +
                """Process items according to config."""
         
     | 
| 
      
 40 
     | 
    
         
            +
                config = config or {}
         
     | 
| 
      
 41 
     | 
    
         
            +
                return {item: len(item) for item in items}
         
     | 
| 
      
 42 
     | 
    
         
            +
            ```
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            ## Error Handling
         
     | 
| 
      
 45 
     | 
    
         
            +
            - Use specific exception types
         
     | 
| 
      
 46 
     | 
    
         
            +
            - Avoid bare except clauses
         
     | 
| 
      
 47 
     | 
    
         
            +
            - Use logging instead of print for debugging
         
     | 
| 
      
 48 
     | 
    
         
            +
            - Fail fast with clear error messages
         
     | 
| 
      
 49 
     | 
    
         
            +
            - Handle exceptions at appropriate levels
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 52 
     | 
    
         
            +
            import logging
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            logger = logging.getLogger(__name__)
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            try:
         
     | 
| 
      
 57 
     | 
    
         
            +
                result = risky_operation()
         
     | 
| 
      
 58 
     | 
    
         
            +
            except ValueError as e:
         
     | 
| 
      
 59 
     | 
    
         
            +
                logger.error(f"Invalid value: {e}")
         
     | 
| 
      
 60 
     | 
    
         
            +
                raise
         
     | 
| 
      
 61 
     | 
    
         
            +
            except Exception as e:
         
     | 
| 
      
 62 
     | 
    
         
            +
                logger.exception("Unexpected error")
         
     | 
| 
      
 63 
     | 
    
         
            +
                # Handle or re-raise appropriately
         
     | 
| 
      
 64 
     | 
    
         
            +
            ```
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            ## Testing with pytest
         
     | 
| 
      
 67 
     | 
    
         
            +
            - Write tests before or alongside implementation
         
     | 
| 
      
 68 
     | 
    
         
            +
            - Use fixtures for test data and setup
         
     | 
| 
      
 69 
     | 
    
         
            +
            - Parametrize tests for multiple scenarios
         
     | 
| 
      
 70 
     | 
    
         
            +
            - Mock external dependencies
         
     | 
| 
      
 71 
     | 
    
         
            +
            - Aim for high coverage but focus on behavior
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 74 
     | 
    
         
            +
            import pytest
         
     | 
| 
      
 75 
     | 
    
         
            +
            from unittest.mock import Mock, patch
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            @pytest.fixture
         
     | 
| 
      
 78 
     | 
    
         
            +
            def sample_data():
         
     | 
| 
      
 79 
     | 
    
         
            +
                return {"key": "value"}
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            @pytest.mark.parametrize("input,expected", [
         
     | 
| 
      
 82 
     | 
    
         
            +
                ("hello", 5),
         
     | 
| 
      
 83 
     | 
    
         
            +
                ("", 0),
         
     | 
| 
      
 84 
     | 
    
         
            +
                ("test", 4),
         
     | 
| 
      
 85 
     | 
    
         
            +
            ])
         
     | 
| 
      
 86 
     | 
    
         
            +
            def test_string_length(input, expected):
         
     | 
| 
      
 87 
     | 
    
         
            +
                assert len(input) == expected
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            def test_with_mock():
         
     | 
| 
      
 90 
     | 
    
         
            +
                mock_service = Mock()
         
     | 
| 
      
 91 
     | 
    
         
            +
                mock_service.get_data.return_value = {"status": "ok"}
         
     | 
| 
      
 92 
     | 
    
         
            +
                assert process_with_service(mock_service)["status"] == "ok"
         
     | 
| 
      
 93 
     | 
    
         
            +
            ```
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            ## Django Specific
         
     | 
| 
      
 96 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 97 
     | 
    
         
            +
            # Models
         
     | 
| 
      
 98 
     | 
    
         
            +
            from django.db import models
         
     | 
| 
      
 99 
     | 
    
         
            +
            from django.urls import reverse
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            class Article(models.Model):
         
     | 
| 
      
 102 
     | 
    
         
            +
                title = models.CharField(max_length=200)
         
     | 
| 
      
 103 
     | 
    
         
            +
                slug = models.SlugField(unique=True)
         
     | 
| 
      
 104 
     | 
    
         
            +
                content = models.TextField()
         
     | 
| 
      
 105 
     | 
    
         
            +
                created_at = models.DateTimeField(auto_now_add=True)
         
     | 
| 
      
 106 
     | 
    
         
            +
                
         
     | 
| 
      
 107 
     | 
    
         
            +
                class Meta:
         
     | 
| 
      
 108 
     | 
    
         
            +
                    ordering = ['-created_at']
         
     | 
| 
      
 109 
     | 
    
         
            +
                
         
     | 
| 
      
 110 
     | 
    
         
            +
                def __str__(self):
         
     | 
| 
      
 111 
     | 
    
         
            +
                    return self.title
         
     | 
| 
      
 112 
     | 
    
         
            +
                
         
     | 
| 
      
 113 
     | 
    
         
            +
                def get_absolute_url(self):
         
     | 
| 
      
 114 
     | 
    
         
            +
                    return reverse('article_detail', args=[self.slug])
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            # Views (Class-Based)
         
     | 
| 
      
 117 
     | 
    
         
            +
            from django.views.generic import ListView, DetailView
         
     | 
| 
      
 118 
     | 
    
         
            +
            from django.contrib.auth.mixins import LoginRequiredMixin
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            class ArticleListView(ListView):
         
     | 
| 
      
 121 
     | 
    
         
            +
                model = Article
         
     | 
| 
      
 122 
     | 
    
         
            +
                paginate_by = 10
         
     | 
| 
      
 123 
     | 
    
         
            +
                context_object_name = 'articles'
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            # Forms
         
     | 
| 
      
 126 
     | 
    
         
            +
            from django import forms
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            class ArticleForm(forms.ModelForm):
         
     | 
| 
      
 129 
     | 
    
         
            +
                class Meta:
         
     | 
| 
      
 130 
     | 
    
         
            +
                    model = Article
         
     | 
| 
      
 131 
     | 
    
         
            +
                    fields = ['title', 'content']
         
     | 
| 
      
 132 
     | 
    
         
            +
                    widgets = {
         
     | 
| 
      
 133 
     | 
    
         
            +
                        'content': forms.Textarea(attrs={'rows': 10}),
         
     | 
| 
      
 134 
     | 
    
         
            +
                    }
         
     | 
| 
      
 135 
     | 
    
         
            +
            ```
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            ## FastAPI Specific
         
     | 
| 
      
 138 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 139 
     | 
    
         
            +
            from fastapi import FastAPI, HTTPException, Depends
         
     | 
| 
      
 140 
     | 
    
         
            +
            from pydantic import BaseModel, Field
         
     | 
| 
      
 141 
     | 
    
         
            +
            from typing import List, Optional
         
     | 
| 
      
 142 
     | 
    
         
            +
            from datetime import datetime
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
            app = FastAPI(title="My API", version="1.0.0")
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            # Pydantic Models
         
     | 
| 
      
 147 
     | 
    
         
            +
            class ItemBase(BaseModel):
         
     | 
| 
      
 148 
     | 
    
         
            +
                name: str = Field(..., min_length=1, max_length=100)
         
     | 
| 
      
 149 
     | 
    
         
            +
                description: Optional[str] = None
         
     | 
| 
      
 150 
     | 
    
         
            +
                price: float = Field(..., gt=0)
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
            class ItemCreate(ItemBase):
         
     | 
| 
      
 153 
     | 
    
         
            +
                pass
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            class Item(ItemBase):
         
     | 
| 
      
 156 
     | 
    
         
            +
                id: int
         
     | 
| 
      
 157 
     | 
    
         
            +
                created_at: datetime
         
     | 
| 
      
 158 
     | 
    
         
            +
                
         
     | 
| 
      
 159 
     | 
    
         
            +
                class Config:
         
     | 
| 
      
 160 
     | 
    
         
            +
                    orm_mode = True
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
            # Dependency Injection
         
     | 
| 
      
 163 
     | 
    
         
            +
            async def get_db():
         
     | 
| 
      
 164 
     | 
    
         
            +
                db = SessionLocal()
         
     | 
| 
      
 165 
     | 
    
         
            +
                try:
         
     | 
| 
      
 166 
     | 
    
         
            +
                    yield db
         
     | 
| 
      
 167 
     | 
    
         
            +
                finally:
         
     | 
| 
      
 168 
     | 
    
         
            +
                    db.close()
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
            # Endpoints
         
     | 
| 
      
 171 
     | 
    
         
            +
            @app.post("/items/", response_model=Item)
         
     | 
| 
      
 172 
     | 
    
         
            +
            async def create_item(
         
     | 
| 
      
 173 
     | 
    
         
            +
                item: ItemCreate, 
         
     | 
| 
      
 174 
     | 
    
         
            +
                db: Session = Depends(get_db)
         
     | 
| 
      
 175 
     | 
    
         
            +
            ):
         
     | 
| 
      
 176 
     | 
    
         
            +
                db_item = ItemModel(**item.dict())
         
     | 
| 
      
 177 
     | 
    
         
            +
                db.add(db_item)
         
     | 
| 
      
 178 
     | 
    
         
            +
                db.commit()
         
     | 
| 
      
 179 
     | 
    
         
            +
                db.refresh(db_item)
         
     | 
| 
      
 180 
     | 
    
         
            +
                return db_item
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
            @app.get("/items/{item_id}", response_model=Item)
         
     | 
| 
      
 183 
     | 
    
         
            +
            async def read_item(item_id: int, db: Session = Depends(get_db)):
         
     | 
| 
      
 184 
     | 
    
         
            +
                item = db.query(ItemModel).filter(ItemModel.id == item_id).first()
         
     | 
| 
      
 185 
     | 
    
         
            +
                if not item:
         
     | 
| 
      
 186 
     | 
    
         
            +
                    raise HTTPException(status_code=404, detail="Item not found")
         
     | 
| 
      
 187 
     | 
    
         
            +
                return item
         
     | 
| 
      
 188 
     | 
    
         
            +
            ```
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
            ## Async/Await Best Practices
         
     | 
| 
      
 191 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 192 
     | 
    
         
            +
            import asyncio
         
     | 
| 
      
 193 
     | 
    
         
            +
            import aiohttp
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
            async def fetch_data(session: aiohttp.ClientSession, url: str) -> dict:
         
     | 
| 
      
 196 
     | 
    
         
            +
                async with session.get(url) as response:
         
     | 
| 
      
 197 
     | 
    
         
            +
                    return await response.json()
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
            async def fetch_multiple(urls: List[str]) -> List[dict]:
         
     | 
| 
      
 200 
     | 
    
         
            +
                async with aiohttp.ClientSession() as session:
         
     | 
| 
      
 201 
     | 
    
         
            +
                    tasks = [fetch_data(session, url) for url in urls]
         
     | 
| 
      
 202 
     | 
    
         
            +
                    return await asyncio.gather(*tasks)
         
     | 
| 
      
 203 
     | 
    
         
            +
            ```
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
            ## Data Validation with Pydantic
         
     | 
| 
      
 206 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 207 
     | 
    
         
            +
            from pydantic import BaseModel, validator, Field
         
     | 
| 
      
 208 
     | 
    
         
            +
            from typing import Optional
         
     | 
| 
      
 209 
     | 
    
         
            +
            from datetime import datetime
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
            class User(BaseModel):
         
     | 
| 
      
 212 
     | 
    
         
            +
                username: str = Field(..., min_length=3, max_length=50)
         
     | 
| 
      
 213 
     | 
    
         
            +
                email: str
         
     | 
| 
      
 214 
     | 
    
         
            +
                age: Optional[int] = Field(None, ge=0, le=150)
         
     | 
| 
      
 215 
     | 
    
         
            +
                created_at: datetime = Field(default_factory=datetime.now)
         
     | 
| 
      
 216 
     | 
    
         
            +
                
         
     | 
| 
      
 217 
     | 
    
         
            +
                @validator('email')
         
     | 
| 
      
 218 
     | 
    
         
            +
                def validate_email(cls, v):
         
     | 
| 
      
 219 
     | 
    
         
            +
                    if '@' not in v:
         
     | 
| 
      
 220 
     | 
    
         
            +
                        raise ValueError('Invalid email')
         
     | 
| 
      
 221 
     | 
    
         
            +
                    return v.lower()
         
     | 
| 
      
 222 
     | 
    
         
            +
            ```
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            ## Database Patterns
         
     | 
| 
      
 225 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 226 
     | 
    
         
            +
            # SQLAlchemy with FastAPI
         
     | 
| 
      
 227 
     | 
    
         
            +
            from sqlalchemy import Column, Integer, String, DateTime
         
     | 
| 
      
 228 
     | 
    
         
            +
            from sqlalchemy.ext.declarative import declarative_base
         
     | 
| 
      
 229 
     | 
    
         
            +
            from sqlalchemy.sql import func
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
            Base = declarative_base()
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
            class UserModel(Base):
         
     | 
| 
      
 234 
     | 
    
         
            +
                __tablename__ = "users"
         
     | 
| 
      
 235 
     | 
    
         
            +
                
         
     | 
| 
      
 236 
     | 
    
         
            +
                id = Column(Integer, primary_key=True, index=True)
         
     | 
| 
      
 237 
     | 
    
         
            +
                username = Column(String, unique=True, index=True)
         
     | 
| 
      
 238 
     | 
    
         
            +
                created_at = Column(DateTime(timezone=True), server_default=func.now())
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
            # Repository Pattern
         
     | 
| 
      
 241 
     | 
    
         
            +
            class UserRepository:
         
     | 
| 
      
 242 
     | 
    
         
            +
                def __init__(self, db: Session):
         
     | 
| 
      
 243 
     | 
    
         
            +
                    self.db = db
         
     | 
| 
      
 244 
     | 
    
         
            +
                
         
     | 
| 
      
 245 
     | 
    
         
            +
                def get_by_username(self, username: str) -> Optional[UserModel]:
         
     | 
| 
      
 246 
     | 
    
         
            +
                    return self.db.query(UserModel).filter(
         
     | 
| 
      
 247 
     | 
    
         
            +
                        UserModel.username == username
         
     | 
| 
      
 248 
     | 
    
         
            +
                    ).first()
         
     | 
| 
      
 249 
     | 
    
         
            +
                
         
     | 
| 
      
 250 
     | 
    
         
            +
                def create(self, user_data: dict) -> UserModel:
         
     | 
| 
      
 251 
     | 
    
         
            +
                    user = UserModel(**user_data)
         
     | 
| 
      
 252 
     | 
    
         
            +
                    self.db.add(user)
         
     | 
| 
      
 253 
     | 
    
         
            +
                    self.db.commit()
         
     | 
| 
      
 254 
     | 
    
         
            +
                    self.db.refresh(user)
         
     | 
| 
      
 255 
     | 
    
         
            +
                    return user
         
     | 
| 
      
 256 
     | 
    
         
            +
            ```
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
            ## Configuration Management
         
     | 
| 
      
 259 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 260 
     | 
    
         
            +
            from pydantic import BaseSettings
         
     | 
| 
      
 261 
     | 
    
         
            +
            from functools import lru_cache
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
            class Settings(BaseSettings):
         
     | 
| 
      
 264 
     | 
    
         
            +
                app_name: str = "My App"
         
     | 
| 
      
 265 
     | 
    
         
            +
                debug: bool = False
         
     | 
| 
      
 266 
     | 
    
         
            +
                database_url: str
         
     | 
| 
      
 267 
     | 
    
         
            +
                secret_key: str
         
     | 
| 
      
 268 
     | 
    
         
            +
                
         
     | 
| 
      
 269 
     | 
    
         
            +
                class Config:
         
     | 
| 
      
 270 
     | 
    
         
            +
                    env_file = ".env"
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
            @lru_cache()
         
     | 
| 
      
 273 
     | 
    
         
            +
            def get_settings():
         
     | 
| 
      
 274 
     | 
    
         
            +
                return Settings()
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
            # Usage
         
     | 
| 
      
 277 
     | 
    
         
            +
            settings = get_settings()
         
     | 
| 
      
 278 
     | 
    
         
            +
            ```
         
     | 
| 
      
 279 
     | 
    
         
            +
             
     | 
| 
      
 280 
     | 
    
         
            +
            ## Logging Best Practices
         
     | 
| 
      
 281 
     | 
    
         
            +
            ```python
         
     | 
| 
      
 282 
     | 
    
         
            +
            import logging
         
     | 
| 
      
 283 
     | 
    
         
            +
            import sys
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
            # Configure logging
         
     | 
| 
      
 286 
     | 
    
         
            +
            logging.basicConfig(
         
     | 
| 
      
 287 
     | 
    
         
            +
                level=logging.INFO,
         
     | 
| 
      
 288 
     | 
    
         
            +
                format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
         
     | 
| 
      
 289 
     | 
    
         
            +
                handlers=[
         
     | 
| 
      
 290 
     | 
    
         
            +
                    logging.StreamHandler(sys.stdout),
         
     | 
| 
      
 291 
     | 
    
         
            +
                    logging.FileHandler('app.log')
         
     | 
| 
      
 292 
     | 
    
         
            +
                ]
         
     | 
| 
      
 293 
     | 
    
         
            +
            )
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
            logger = logging.getLogger(__name__)
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
      
 297 
     | 
    
         
            +
            # Use structured logging
         
     | 
| 
      
 298 
     | 
    
         
            +
            logger.info(
         
     | 
| 
      
 299 
     | 
    
         
            +
                "User action", 
         
     | 
| 
      
 300 
     | 
    
         
            +
                extra={"user_id": 123, "action": "login", "ip": "192.168.1.1"}
         
     | 
| 
      
 301 
     | 
    
         
            +
            )
         
     | 
| 
      
 302 
     | 
    
         
            +
            ```
         
     | 
| 
      
 303 
     | 
    
         
            +
             
     | 
| 
      
 304 
     | 
    
         
            +
            ## Performance Optimization
         
     | 
| 
      
 305 
     | 
    
         
            +
            - Use generators for large datasets
         
     | 
| 
      
 306 
     | 
    
         
            +
            - Cache expensive operations with functools.lru_cache
         
     | 
| 
      
 307 
     | 
    
         
            +
            - Profile code with cProfile before optimizing
         
     | 
| 
      
 308 
     | 
    
         
            +
            - Use appropriate data structures (sets for membership, deque for queues)
         
     | 
| 
      
 309 
     | 
    
         
            +
            - Leverage asyncio for I/O-bound operations
         
     | 
| 
      
 310 
     | 
    
         
            +
            - Consider multiprocessing for CPU-bound tasks
         
     | 
| 
      
 311 
     | 
    
         
            +
             
     | 
| 
      
 312 
     | 
    
         
            +
            ## Security Best Practices
         
     | 
| 
      
 313 
     | 
    
         
            +
            - Never hardcode secrets
         
     | 
| 
      
 314 
     | 
    
         
            +
            - Use environment variables for configuration
         
     | 
| 
      
 315 
     | 
    
         
            +
            - Validate all input data
         
     | 
| 
      
 316 
     | 
    
         
            +
            - Use parameterized queries to prevent SQL injection
         
     | 
| 
      
 317 
     | 
    
         
            +
            - Hash passwords with bcrypt or argon2
         
     | 
| 
      
 318 
     | 
    
         
            +
            - Implement proper authentication and authorization
         
     | 
| 
      
 319 
     | 
    
         
            +
            - Keep dependencies updated
         
     | 
| 
      
 320 
     | 
    
         
            +
             
     | 
| 
      
 321 
     | 
    
         
            +
            ## Common Pitfalls to Avoid
         
     | 
| 
      
 322 
     | 
    
         
            +
            - Mutable default arguments
         
     | 
| 
      
 323 
     | 
    
         
            +
            - Modifying lists while iterating
         
     | 
| 
      
 324 
     | 
    
         
            +
            - Using `is` for value comparison (use `==`)
         
     | 
| 
      
 325 
     | 
    
         
            +
            - Catching too broad exceptions
         
     | 
| 
      
 326 
     | 
    
         
            +
            - Not closing resources properly
         
     | 
| 
      
 327 
     | 
    
         
            +
            - Circular imports
         
     | 
| 
      
 328 
     | 
    
         
            +
            - Using global variables excessively
         
     | 
| 
      
 329 
     | 
    
         
            +
             
     | 
| 
      
 330 
     | 
    
         
            +
            Remember: "Explicit is better than implicit" - The Zen of Python
         
     | 
    
        data/lib/chiron/version.rb
    CHANGED
    
    
    
        data/lib/chiron.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: chiron
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.2.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Brett McHargue
         
     | 
| 
         @@ -108,7 +108,7 @@ dependencies: 
     | 
|
| 
       108 
108 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       109 
109 
     | 
    
         
             
                    version: '1.21'
         
     | 
| 
       110 
110 
     | 
    
         
             
            description: A Ruby gem that sets up Claude AI development workflows, PRD templates,
         
     | 
| 
       111 
     | 
    
         
            -
              and journaling system for Rails projects
         
     | 
| 
      
 111 
     | 
    
         
            +
              and journaling system for Rails and Python projects
         
     | 
| 
       112 
112 
     | 
    
         
             
            email:
         
     | 
| 
       113 
113 
     | 
    
         
             
            - ebrett@users.noreply.github.com
         
     | 
| 
       114 
114 
     | 
    
         
             
            executables:
         
     | 
| 
         @@ -130,21 +130,24 @@ files: 
     | 
|
| 
       130 
130 
     | 
    
         
             
            - exe/chiron
         
     | 
| 
       131 
131 
     | 
    
         
             
            - lib/chiron.rb
         
     | 
| 
       132 
132 
     | 
    
         
             
            - lib/chiron/cli.rb
         
     | 
| 
       133 
     | 
    
         
            -
            - lib/chiron/ 
     | 
| 
       134 
     | 
    
         
            -
            - lib/chiron/templates/ 
     | 
| 
       135 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       136 
     | 
    
         
            -
            - lib/chiron/templates/ 
     | 
| 
       137 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       138 
     | 
    
         
            -
            - lib/chiron/templates/ 
     | 
| 
       139 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       140 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       141 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       142 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       143 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       144 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       145 
     | 
    
         
            -
            - lib/chiron/templates/commands/ 
     | 
| 
       146 
     | 
    
         
            -
            - lib/chiron/templates/commands/workflows/ 
     | 
| 
       147 
     | 
    
         
            -
            - lib/chiron/templates/ 
     | 
| 
      
 133 
     | 
    
         
            +
            - lib/chiron/project_config.rb
         
     | 
| 
      
 134 
     | 
    
         
            +
            - lib/chiron/templates/python/CLAUDE.md.erb
         
     | 
| 
      
 135 
     | 
    
         
            +
            - lib/chiron/templates/python/commands/conventions/python.md
         
     | 
| 
      
 136 
     | 
    
         
            +
            - lib/chiron/templates/rails/CLAUDE.md.erb
         
     | 
| 
      
 137 
     | 
    
         
            +
            - lib/chiron/templates/rails/commands/conventions/rails.md
         
     | 
| 
      
 138 
     | 
    
         
            +
            - lib/chiron/templates/shared/claude/settings.json
         
     | 
| 
      
 139 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/context/catchup.md
         
     | 
| 
      
 140 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/context/prime.md
         
     | 
| 
      
 141 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/context/quickstart.md
         
     | 
| 
      
 142 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/journal/instructions.md
         
     | 
| 
      
 143 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/journal/template.md
         
     | 
| 
      
 144 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/quality/pre-commit.md
         
     | 
| 
      
 145 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/quality/test-driven.md
         
     | 
| 
      
 146 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/workflows/create-prd.md
         
     | 
| 
      
 147 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/workflows/feature-complete.md
         
     | 
| 
      
 148 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/workflows/generate-tasks.md
         
     | 
| 
      
 149 
     | 
    
         
            +
            - lib/chiron/templates/shared/commands/workflows/process-tasks.md
         
     | 
| 
      
 150 
     | 
    
         
            +
            - lib/chiron/templates/shared/development_journal.md.erb
         
     | 
| 
       148 
151 
     | 
    
         
             
            - lib/chiron/version.rb
         
     | 
| 
       149 
152 
     | 
    
         
             
            homepage: https://github.com/ebrett/chiron
         
     | 
| 
       150 
153 
     | 
    
         
             
            licenses:
         
     | 
| 
         @@ -170,5 +173,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       170 
173 
     | 
    
         
             
            requirements: []
         
     | 
| 
       171 
174 
     | 
    
         
             
            rubygems_version: 3.6.2
         
     | 
| 
       172 
175 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       173 
     | 
    
         
            -
            summary: Initialize Claude AI workflow for Rails projects
         
     | 
| 
      
 176 
     | 
    
         
            +
            summary: Initialize Claude AI workflow for Rails and Python projects
         
     | 
| 
       174 
177 
     | 
    
         
             
            test_files: []
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     |