chiron 0.2.0 → 0.2.2

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.
@@ -0,0 +1,336 @@
1
+ # Python Refactoring Workflow
2
+
3
+ Follow this systematic approach when refactoring Python code to improve its structure, readability, and maintainability.
4
+
5
+ ## Pre-Refactoring Checklist
6
+
7
+ - [ ] Ensure comprehensive test coverage exists
8
+ - [ ] Run all tests and confirm they pass
9
+ - [ ] Commit current working state to version control
10
+ - [ ] Identify specific refactoring goals
11
+ - [ ] Review Python conventions and PEP 8
12
+
13
+ ## Refactoring Patterns
14
+
15
+ ### 1. Extract Function
16
+ ```python
17
+ # Before
18
+ def process_user_data(users):
19
+ for user in users:
20
+ # Complex validation logic
21
+ if user.age < 18:
22
+ user.status = 'minor'
23
+ elif user.age >= 65:
24
+ user.status = 'senior'
25
+ else:
26
+ user.status = 'adult'
27
+
28
+ # Complex calculation
29
+ user.discount = calculate_complex_discount(user)
30
+
31
+ # After
32
+ def process_user_data(users):
33
+ for user in users:
34
+ user.status = categorize_user_by_age(user.age)
35
+ user.discount = calculate_user_discount(user)
36
+
37
+ def categorize_user_by_age(age: int) -> str:
38
+ if age < 18:
39
+ return 'minor'
40
+ elif age >= 65:
41
+ return 'senior'
42
+ return 'adult'
43
+ ```
44
+
45
+ ### 2. Extract Class
46
+ ```python
47
+ # Before
48
+ def send_email(to, subject, body, smtp_server, port, username, password):
49
+ # Email sending logic
50
+ pass
51
+
52
+ # After
53
+ class EmailService:
54
+ def __init__(self, smtp_server: str, port: int, username: str, password: str):
55
+ self.smtp_server = smtp_server
56
+ self.port = port
57
+ self.username = username
58
+ self.password = password
59
+
60
+ def send(self, to: str, subject: str, body: str) -> None:
61
+ # Email sending logic
62
+ pass
63
+
64
+ # Usage
65
+ email_service = EmailService(smtp_server, port, username, password)
66
+ email_service.send(to, subject, body)
67
+ ```
68
+
69
+ ### 3. Replace Conditionals with Polymorphism
70
+ ```python
71
+ # Before
72
+ def calculate_shipping(order_type, weight, distance):
73
+ if order_type == 'standard':
74
+ return weight * 0.5 + distance * 0.1
75
+ elif order_type == 'express':
76
+ return weight * 1.0 + distance * 0.2
77
+ elif order_type == 'overnight':
78
+ return weight * 2.0 + distance * 0.5
79
+
80
+ # After
81
+ from abc import ABC, abstractmethod
82
+
83
+ class ShippingStrategy(ABC):
84
+ @abstractmethod
85
+ def calculate(self, weight: float, distance: float) -> float:
86
+ pass
87
+
88
+ class StandardShipping(ShippingStrategy):
89
+ def calculate(self, weight: float, distance: float) -> float:
90
+ return weight * 0.5 + distance * 0.1
91
+
92
+ class ExpressShipping(ShippingStrategy):
93
+ def calculate(self, weight: float, distance: float) -> float:
94
+ return weight * 1.0 + distance * 0.2
95
+
96
+ class OvernightShipping(ShippingStrategy):
97
+ def calculate(self, weight: float, distance: float) -> float:
98
+ return weight * 2.0 + distance * 0.5
99
+
100
+ # Usage
101
+ shipping_strategies = {
102
+ 'standard': StandardShipping(),
103
+ 'express': ExpressShipping(),
104
+ 'overnight': OvernightShipping()
105
+ }
106
+
107
+ def calculate_shipping(order_type: str, weight: float, distance: float) -> float:
108
+ strategy = shipping_strategies.get(order_type)
109
+ if not strategy:
110
+ raise ValueError(f"Unknown order type: {order_type}")
111
+ return strategy.calculate(weight, distance)
112
+ ```
113
+
114
+ ### 4. Simplify Complex Conditionals
115
+ ```python
116
+ # Before
117
+ def can_withdraw(account, amount):
118
+ if account.balance >= amount and account.is_active and not account.is_frozen and amount > 0:
119
+ return True
120
+ return False
121
+
122
+ # After
123
+ def can_withdraw(account, amount):
124
+ has_sufficient_funds = account.balance >= amount
125
+ is_valid_amount = amount > 0
126
+ is_account_available = account.is_active and not account.is_frozen
127
+
128
+ return has_sufficient_funds and is_valid_amount and is_account_available
129
+ ```
130
+
131
+ ### 5. Use List Comprehensions and Generators
132
+ ```python
133
+ # Before
134
+ def get_active_user_emails(users):
135
+ emails = []
136
+ for user in users:
137
+ if user.is_active:
138
+ emails.append(user.email)
139
+ return emails
140
+
141
+ # After
142
+ def get_active_user_emails(users):
143
+ return [user.email for user in users if user.is_active]
144
+
145
+ # For large datasets, use generator
146
+ def get_active_user_emails_generator(users):
147
+ return (user.email for user in users if user.is_active)
148
+ ```
149
+
150
+ ### 6. Replace Magic Numbers with Named Constants
151
+ ```python
152
+ # Before
153
+ def calculate_circle_area(radius):
154
+ return 3.14159 * radius ** 2
155
+
156
+ def is_valid_age(age):
157
+ return 18 <= age <= 65
158
+
159
+ # After
160
+ import math
161
+
162
+ MINIMUM_AGE = 18
163
+ RETIREMENT_AGE = 65
164
+
165
+ def calculate_circle_area(radius):
166
+ return math.pi * radius ** 2
167
+
168
+ def is_valid_age(age):
169
+ return MINIMUM_AGE <= age <= RETIREMENT_AGE
170
+ ```
171
+
172
+ ### 7. Use Type Hints
173
+ ```python
174
+ # Before
175
+ def process_items(items, multiplier):
176
+ return [item * multiplier for item in items]
177
+
178
+ # After
179
+ from typing import List, Union
180
+
181
+ def process_items(
182
+ items: List[Union[int, float]],
183
+ multiplier: Union[int, float]
184
+ ) -> List[Union[int, float]]:
185
+ return [item * multiplier for item in items]
186
+ ```
187
+
188
+ ### 8. Replace Nested Loops with Iterator Tools
189
+ ```python
190
+ # Before
191
+ def get_combinations(list1, list2):
192
+ result = []
193
+ for item1 in list1:
194
+ for item2 in list2:
195
+ result.append((item1, item2))
196
+ return result
197
+
198
+ # After
199
+ from itertools import product
200
+
201
+ def get_combinations(list1, list2):
202
+ return list(product(list1, list2))
203
+ ```
204
+
205
+ ## Code Organization Refactoring
206
+
207
+ ### 1. Module Structure
208
+ ```python
209
+ # Before: everything in one file
210
+ # app.py (1000+ lines)
211
+
212
+ # After: organized modules
213
+ # project/
214
+ # ├── __init__.py
215
+ # ├── models/
216
+ # │ ├── __init__.py
217
+ # │ ├── user.py
218
+ # │ └── order.py
219
+ # ├── services/
220
+ # │ ├── __init__.py
221
+ # │ ├── email_service.py
222
+ # │ └── payment_service.py
223
+ # └── utils/
224
+ # ├── __init__.py
225
+ # └── validators.py
226
+ ```
227
+
228
+ ### 2. Dependency Injection
229
+ ```python
230
+ # Before
231
+ class OrderService:
232
+ def process_order(self, order):
233
+ db = Database() # Hard-coded dependency
234
+ payment = PaymentGateway() # Hard-coded dependency
235
+ # Process order
236
+
237
+ # After
238
+ class OrderService:
239
+ def __init__(self, db: Database, payment_gateway: PaymentGateway):
240
+ self.db = db
241
+ self.payment_gateway = payment_gateway
242
+
243
+ def process_order(self, order):
244
+ # Process order using injected dependencies
245
+ ```
246
+
247
+ ## Testing During Refactoring
248
+
249
+ ### 1. Maintain Test Coverage
250
+ ```bash
251
+ # Run tests with coverage
252
+ pytest --cov=myproject tests/
253
+
254
+ # Generate coverage report
255
+ pytest --cov=myproject --cov-report=html tests/
256
+ ```
257
+
258
+ ### 2. Test Each Refactoring Step
259
+ ```python
260
+ # Write characterization tests before refactoring
261
+ def test_original_behavior():
262
+ # Capture current behavior
263
+ result = legacy_function(test_input)
264
+ assert result == expected_output
265
+
266
+ # Ensure behavior remains the same after refactoring
267
+ def test_refactored_behavior():
268
+ result = refactored_function(test_input)
269
+ assert result == expected_output
270
+ ```
271
+
272
+ ## Performance Considerations
273
+
274
+ ### 1. Profile Before and After
275
+ ```python
276
+ import cProfile
277
+ import pstats
278
+
279
+ # Profile original code
280
+ cProfile.run('original_function()', 'original_stats')
281
+
282
+ # Profile refactored code
283
+ cProfile.run('refactored_function()', 'refactored_stats')
284
+
285
+ # Compare results
286
+ original = pstats.Stats('original_stats')
287
+ refactored = pstats.Stats('refactored_stats')
288
+ ```
289
+
290
+ ### 2. Memory Usage
291
+ ```python
292
+ from memory_profiler import profile
293
+
294
+ @profile
295
+ def function_to_refactor():
296
+ # Your code here
297
+ pass
298
+ ```
299
+
300
+ ## Refactoring Tools
301
+
302
+ ### 1. Automated Refactoring with rope
303
+ ```bash
304
+ pip install rope
305
+
306
+ # Use rope for automated refactoring
307
+ # - Extract method
308
+ # - Rename
309
+ # - Move
310
+ # - Inline
311
+ ```
312
+
313
+ ### 2. Code Formatting
314
+ ```bash
315
+ # Format with black
316
+ black myproject/
317
+
318
+ # Sort imports with isort
319
+ isort myproject/
320
+
321
+ # Type check with mypy
322
+ mypy myproject/
323
+ ```
324
+
325
+ ## Post-Refactoring Checklist
326
+
327
+ - [ ] All tests pass
328
+ - [ ] Code coverage maintained or improved
329
+ - [ ] Performance is acceptable
330
+ - [ ] Code follows PEP 8 and project conventions
331
+ - [ ] Type hints added where appropriate
332
+ - [ ] Documentation updated
333
+ - [ ] Complex parts have explanatory comments
334
+ - [ ] No code duplication
335
+ - [ ] SOLID principles followed
336
+ - [ ] Code reviewed by team member
@@ -6,6 +6,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
6
6
 
7
7
  <%= @project_name %> is a Rails <%= Rails.version rescue "8.0.2" %> application. [Add your project description here]
8
8
 
9
+ ## Tool Permissions & Customization
10
+
11
+ ```bash
12
+ # View current tool permissions
13
+ /permissions
14
+
15
+ # Customize tools for specific sessions
16
+ claude --allowedTools read,edit,bash --no-write # Example: read-only session
17
+ claude --allowedTools bash,read,write # Example: development session
18
+ ```
19
+
9
20
  ## Development Commands
10
21
 
11
22
  **Important**: Always use binstubs instead of `bundle exec` for better performance and consistency.
@@ -67,6 +78,17 @@ Required for development:
67
78
 
68
79
  ## Development Patterns
69
80
 
81
+ ### Explore-Plan-Code-Commit Workflow
82
+ 1. **Explore**: Read relevant files and understand context
83
+ 2. **Plan**: Use "think" to trigger extended thinking mode for complex problems
84
+ 3. **Code**: Implement solution incrementally with frequent testing
85
+ 4. **Commit**: Create clear commit messages explaining the change
86
+
87
+ ### Visual Development
88
+ - Take screenshots for UI work using Claude Code's image reading
89
+ - Iterate 2-3 times for visual improvements
90
+ - Use incremental screenshots to track progress
91
+
70
92
  ### Component Architecture
71
93
  - Use ViewComponent for reusable UI elements (located in `app/components/`)
72
94
  - Follow Rails conventions with Hotwire for reactive interfaces
@@ -85,13 +107,23 @@ Required for development:
85
107
  ## Testing Standards
86
108
 
87
109
  - Write tests before implementation (TDD)
88
- - Maintain high test coverage
110
+ - **Verify tests fail first** - Confirm tests fail before writing implementation
111
+ - Maintain high test coverage but avoid "overfitting to the tests"
89
112
  - Use FactoryBot for test data
90
113
  - Follow RSpec best practices
114
+ - Test both happy path and edge cases
115
+
116
+ ## Quick Documentation Tips
117
+
118
+ - Use `#` key to quickly document guidelines and patterns
119
+ - Be specific in instructions to Claude
120
+ - Course-correct early and often during development
121
+ - Provide clear context and expectations
91
122
 
92
123
  ## Important Reminders
93
124
 
94
125
  - Always run tests before committing
95
- - Use semantic commit messages
126
+ - Use semantic commit messages with clear explanations
96
127
  - Update the development journal for significant changes
97
- - Follow the pre-commit checklist in `.claude/commands/quality/pre-commit.md`
128
+ - Follow the pre-commit checklist in `.claude/commands/quality/pre-commit.md`
129
+ - Use conversational Q&A to explore unfamiliar parts of the codebase
@@ -0,0 +1,176 @@
1
+ # Branch Context Command
2
+
3
+ Use this command when switching branches, starting new work, or when Claude needs to understand the current branch context.
4
+
5
+ ## Purpose
6
+
7
+ Provides comprehensive branch information to maintain context across Claude sessions, especially important when:
8
+ - Switching between branches
9
+ - Starting a new Claude session on an existing branch
10
+ - Collaborating with others on feature branches
11
+ - Resuming work after time away
12
+
13
+ ## Process
14
+
15
+ ### 1. **Current Branch Status**
16
+ ```bash
17
+ git branch --show-current
18
+ git status --porcelain
19
+ git log --oneline -5
20
+ ```
21
+
22
+ ### 2. **Branch Information**
23
+ ```bash
24
+ # Show branch creation point
25
+ git merge-base main HEAD
26
+
27
+ # Show commits unique to this branch
28
+ git log --oneline main..HEAD
29
+
30
+ # Show files changed in this branch
31
+ git diff --name-only main...HEAD
32
+ ```
33
+
34
+ ### 3. **Branch Purpose Discovery**
35
+ Check for:
36
+ - **Tasks Directory**: Look for related PRD files in `/tasks/`
37
+ - **Development Journal**: Search for branch-related entries
38
+ - **Commit Messages**: Analyze recent commits for context
39
+ - **Pull Request**: Check if PR exists for this branch
40
+
41
+ ### 4. **Work Context**
42
+ ```bash
43
+ # Check for uncommitted work
44
+ git diff --stat
45
+
46
+ # Check for untracked files
47
+ git ls-files --others --exclude-standard
48
+
49
+ # Check for stashed changes
50
+ git stash list
51
+ ```
52
+
53
+ ## Output Format
54
+
55
+ Provide a structured summary:
56
+
57
+ ### Branch Overview
58
+ - **Name**: Current branch name
59
+ - **Type**: feature/bugfix/hotfix/experiment
60
+ - **Base**: Branch point from main/develop
61
+ - **Age**: How long since branch creation
62
+ - **Status**: ahead/behind/up-to-date with base
63
+
64
+ ### Current Work
65
+ - **Purpose**: What this branch is implementing
66
+ - **Progress**: Completed vs remaining work
67
+ - **Files Modified**: Key files changed
68
+ - **Tests**: Test status and coverage
69
+
70
+ ### Context for Claude
71
+ - **Related PRD**: Link to requirements document
72
+ - **Dependencies**: Other branches or external dependencies
73
+ - **Blockers**: Known issues or waiting items
74
+ - **Next Steps**: Immediate tasks to continue
75
+
76
+ ## Example Response
77
+
78
+ ```
79
+ 🌿 **Branch Context: feature/python-support**
80
+
81
+ **Overview:**
82
+ - Type: Feature branch
83
+ - Created: 3 days ago from main
84
+ - Status: 15 commits ahead of main
85
+ - Purpose: Add comprehensive Python project support to Chiron
86
+
87
+ **Current State:**
88
+ - 📁 Files changed: 25 files (mostly new Python templates)
89
+ - ✅ Tests: 41 examples, all passing
90
+ - 📝 Documentation: README and CHANGELOG updated
91
+ - 🚀 Status: Ready for merge
92
+
93
+ **Work Completed:**
94
+ - ✅ Python project detection (Django, FastAPI, Flask)
95
+ - ✅ ProjectConfig class for language abstraction
96
+ - ✅ Python workflow templates created
97
+ - ✅ Comprehensive test coverage added
98
+
99
+ **Context for Claude:**
100
+ - PRD: Located at tasks/prd-python-support.md
101
+ - Dependencies: None
102
+ - Blockers: None
103
+ - Next: Final review and merge to main
104
+
105
+ **Recommended Actions:**
106
+ 1. Run final test suite
107
+ 2. Update version number for release
108
+ 3. Create pull request for review
109
+ ```
110
+
111
+ ## Command Variations
112
+
113
+ ### Quick Branch Info
114
+ ```bash
115
+ # Just the essentials
116
+ git branch --show-current && git status --short && git log --oneline -3
117
+ ```
118
+
119
+ ### Detailed Branch Analysis
120
+ ```bash
121
+ # Comprehensive branch analysis
122
+ git log --graph --oneline --all -10
123
+ git diff --stat main...HEAD
124
+ ```
125
+
126
+ ### Branch Comparison
127
+ ```bash
128
+ # Compare with main branch
129
+ git log --left-right --graph --cherry-pick --oneline main...HEAD
130
+ ```
131
+
132
+ ## Integration with Other Commands
133
+
134
+ ### Use with Quickstart
135
+ - Automatically called when starting work session
136
+ - Provides branch context before task planning
137
+
138
+ ### Use with Catchup
139
+ - Shows branch progress in relation to project goals
140
+ - Identifies if branch work aligns with current priorities
141
+
142
+ ### Use before PRs
143
+ - Ensures all branch work is documented
144
+ - Confirms branch is ready for review
145
+
146
+ ## Tips for Effective Branch Tracking
147
+
148
+ ### Branch Naming
149
+ - Use prefixes: `feature/`, `bugfix/`, `hotfix/`, `experiment/`
150
+ - Include ticket numbers: `feature/PROJ-123-user-auth`
151
+ - Be descriptive: `feature/python-project-support`
152
+
153
+ ### Commit Messages
154
+ - Reference related issues or PRDs
155
+ - Use conventional commits format
156
+ - Include context for future sessions
157
+
158
+ ### Documentation
159
+ - Update journal when creating branches
160
+ - Link branches to PRDs or task lists
161
+ - Note collaboration context
162
+
163
+ ### Session Continuity
164
+ - Run this command at session start
165
+ - Update when switching branches
166
+ - Use before major commits or pushes
167
+
168
+ ## Automation Opportunities
169
+
170
+ Consider adding git hooks to:
171
+ - Auto-update journal on branch creation
172
+ - Prompt for branch purpose on first commit
173
+ - Remind about documentation updates
174
+ - Check for related PRD files
175
+
176
+ This command ensures Claude always has full context about your current branch and work progress, making sessions more productive and reducing ramp-up time.
@@ -22,7 +22,12 @@ Use this when the user asks "catchup", "where are we", or wants a project status
22
22
  git log --oneline -5
23
23
  ```
24
24
 
25
- 4. **Test Status**
25
+ 4. **Get Branch Context**
26
+ - Run `/branch-context` command for detailed branch information
27
+ - Check branch purpose and progress
28
+ - Review commits unique to this branch
29
+
30
+ 5. **Test Status**
26
31
  ```bash
27
32
  bin/rspec --format progress | tail -5
28
33
  ```
@@ -15,16 +15,21 @@ Use this command to quickly get up to speed with the current project state.
15
15
  git branch --show-current
16
16
  ```
17
17
 
18
- 3. **Review Recent Work**
18
+ 3. **Get Branch Context**
19
+ - Run `/branch-context` command if not on main branch
20
+ - Understand current branch purpose and progress
21
+ - Check for any uncommitted work or stashes
22
+
23
+ 4. **Review Recent Work**
19
24
  - READ: docs/development_journal.md (last 3 entries)
20
25
  - Check for active tasks in /tasks/ directory
21
26
 
22
- 4. **Quick Test Status**
27
+ 5. **Quick Test Status**
23
28
  ```bash
24
29
  bin/rspec --fail-fast
25
30
  ```
26
31
 
27
- 5. **Check Code Quality**
32
+ 6. **Check Code Quality**
28
33
  ```bash
29
34
  bin/rubocop --format simple | tail -20
30
35
  ```
@@ -2,13 +2,20 @@
2
2
 
3
3
  ## Core Principles
4
4
 
5
- 1. **Red**: Write a failing test first
5
+ 1. **Red**: Write a failing test first and **verify it fails**
6
6
  2. **Green**: Write minimal code to make the test pass
7
7
  3. **Refactor**: Improve the code while keeping tests green
8
8
 
9
+ ## Key: Always Verify Test Failure First
10
+
11
+ **Critical**: Before writing implementation, run the test to confirm it fails for the expected reason. This prevents false positives and ensures your test actually validates the behavior.
12
+
9
13
  ## TDD Process
10
14
 
11
- ### Step 1: Write a Failing Test
15
+ ### Step 1: Think Through Complex Features
16
+ For complex functionality, use "think" to trigger extended thinking mode to plan your test strategy.
17
+
18
+ ### Step 2: Write a Failing Test
12
19
  ```ruby
13
20
  # spec/models/user_spec.rb
14
21
  it 'returns the full name' do
@@ -17,13 +24,14 @@ it 'returns the full name' do
17
24
  end
18
25
  ```
19
26
 
20
- ### Step 2: Run Test (See it Fail)
27
+ ### Step 3: **VERIFY** Test Fails (Critical Step)
21
28
  ```bash
22
29
  bin/rspec spec/models/user_spec.rb
23
30
  # Expected failure: undefined method `full_name'
31
+ # CONFIRM: Test fails for the RIGHT reason
24
32
  ```
25
33
 
26
- ### Step 3: Write Minimal Code
34
+ ### Step 4: Write Minimal Code
27
35
  ```ruby
28
36
  # app/models/user.rb
29
37
  def full_name
@@ -31,13 +39,13 @@ def full_name
31
39
  end
32
40
  ```
33
41
 
34
- ### Step 4: Run Test (See it Pass)
42
+ ### Step 5: Run Test (See it Pass)
35
43
  ```bash
36
44
  bin/rspec spec/models/user_spec.rb
37
45
  # All tests should pass
38
46
  ```
39
47
 
40
- ### Step 5: Refactor if Needed
48
+ ### Step 6: Refactor if Needed
41
49
  ```ruby
42
50
  # Improved version
43
51
  def full_name
@@ -68,6 +76,8 @@ end
68
76
  - Never delete or modify tests just to make them pass
69
77
  - If a test is wrong, fix it and document why
70
78
  - Use `skip` or `pending` for incomplete tests
79
+ - **Avoid overfitting**: Ensure tests validate real behavior, not just current implementation
80
+ - Write tests that would catch regressions if the implementation changed
71
81
 
72
82
  ## Test Plan Management
73
83