@botlearn/refactor 0.1.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.
- package/LICENSE +21 -0
- package/README.md +35 -0
- package/knowledge/anti-patterns.md +92 -0
- package/knowledge/best-practices.md +147 -0
- package/knowledge/domain.md +193 -0
- package/manifest.json +28 -0
- package/package.json +38 -0
- package/skill.md +48 -0
- package/strategies/main.md +150 -0
- package/tests/benchmark.json +496 -0
- package/tests/smoke.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 BotLearn
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @botlearn/refactor
|
|
2
|
+
|
|
3
|
+
> Automated code refactoring with design pattern application, complexity reduction, and behavioral equivalence verification for OpenClaw Agent
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# via npm
|
|
9
|
+
npm install @botlearn/refactor
|
|
10
|
+
|
|
11
|
+
# via clawhub
|
|
12
|
+
clawhub install @botlearn/refactor
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Category
|
|
16
|
+
|
|
17
|
+
programming-assistance
|
|
18
|
+
|
|
19
|
+
## Dependencies
|
|
20
|
+
|
|
21
|
+
`@botlearn/code-review`
|
|
22
|
+
|
|
23
|
+
## Files
|
|
24
|
+
|
|
25
|
+
| File | Description |
|
|
26
|
+
|------|-------------|
|
|
27
|
+
| `manifest.json` | Skill metadata and configuration |
|
|
28
|
+
| `skill.md` | Role definition and activation rules |
|
|
29
|
+
| `knowledge/` | Domain knowledge documents |
|
|
30
|
+
| `strategies/` | Behavioral strategy definitions |
|
|
31
|
+
| `tests/` | Smoke and benchmark tests |
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
MIT
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
domain: refactor
|
|
3
|
+
topic: refactoring-anti-patterns
|
|
4
|
+
priority: medium
|
|
5
|
+
ttl: 30d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Code Refactoring — Anti-Patterns
|
|
9
|
+
|
|
10
|
+
## Planning Anti-Patterns
|
|
11
|
+
|
|
12
|
+
### 1. Big-Bang Refactor
|
|
13
|
+
- **Problem**: Attempting to refactor an entire module, class, or system in a single large change; rewriting from scratch under the guise of "refactoring"
|
|
14
|
+
- **Consequences**: Merge conflicts with ongoing feature work; impossible to isolate introduced bugs; no rollback point; multi-day or multi-week branches that diverge from main; high risk of abandonment
|
|
15
|
+
- **Fix**: Decompose into the smallest possible independent steps; each step modifies one structural element (one method, one class, one dependency); each step is a separate commit with passing tests; use the Strangler Fig pattern for large-scale migrations
|
|
16
|
+
|
|
17
|
+
### 2. Refactoring Without Tests
|
|
18
|
+
- **Problem**: Restructuring code that has no test coverage and writing no characterization tests before beginning
|
|
19
|
+
- **Consequences**: No safety net to detect behavioral changes; silent regressions discovered weeks later in production; loss of team confidence in the codebase
|
|
20
|
+
- **Fix**: Write characterization tests first — capture existing behavior as-is, even if the behavior seems incorrect; achieve at least 80% line coverage and 70% branch coverage on the target code before making any structural changes; if tests are impractical, use snapshot testing to record input/output pairs
|
|
21
|
+
|
|
22
|
+
### 3. Refactoring Without Measuring
|
|
23
|
+
- **Problem**: Performing refactoring based on gut feeling without measuring code quality before or after
|
|
24
|
+
- **Consequences**: No evidence that the refactoring improved anything; possible degradation disguised as improvement; no way to justify the investment to stakeholders
|
|
25
|
+
- **Fix**: Measure cyclomatic complexity, cognitive complexity, coupling, and duplication before starting; set explicit improvement targets; measure after completion; report the delta
|
|
26
|
+
|
|
27
|
+
### 4. Scope Creep Refactoring
|
|
28
|
+
- **Problem**: Starting with a focused refactoring target but continuously expanding scope as new issues are discovered ("while I'm here, I'll also fix this...")
|
|
29
|
+
- **Consequences**: Unbounded work; touching unrelated code increases risk; delays the original goal; makes the changeset unreviewable
|
|
30
|
+
- **Fix**: Define a strict boundary before starting; log discovered issues as separate tasks; complete the original scope first; address new issues in subsequent, independent refactoring sessions
|
|
31
|
+
|
|
32
|
+
## Execution Anti-Patterns
|
|
33
|
+
|
|
34
|
+
### 5. Premature Abstraction
|
|
35
|
+
- **Problem**: Introducing design patterns, abstract classes, or generic interfaces before there is concrete evidence of the need for extensibility — typically after seeing only 1 concrete case
|
|
36
|
+
- **Consequences**: Over-engineered code that is harder to understand than the original; abstractions that don't match actual variation points; increased indirection with no benefit; refactoring the refactoring later
|
|
37
|
+
- **Rule of Three**: Wait until you have 3 concrete instances of duplication or variation before introducing an abstraction; 2 instances are a coincidence, 3 are a pattern
|
|
38
|
+
- **Fix**: Start concrete, generalize only when variation is demonstrated; prefer duplication over the wrong abstraction
|
|
39
|
+
|
|
40
|
+
### 6. Pattern Fever
|
|
41
|
+
- **Problem**: Applying GoF design patterns because they are "good practices" rather than because they solve a specific identified problem in the code
|
|
42
|
+
- **Consequences**: Unnecessary complexity; explosion of small classes and interfaces that obscure simple logic; Factory patterns wrapping a single constructor; Strategy patterns with a single strategy; Observer patterns where a direct call suffices
|
|
43
|
+
- **Fix**: Every pattern application must reference a specific code smell it resolves; if you cannot name the smell, you do not need the pattern; after applying a pattern, verify that the code is easier to understand, not harder
|
|
44
|
+
|
|
45
|
+
### 7. Refactoring in Production Hotfix Branches
|
|
46
|
+
- **Problem**: Combining refactoring changes with bug fixes in the same commit or branch
|
|
47
|
+
- **Consequences**: Difficult to review — reviewer cannot separate intentional behavior changes (fix) from structural changes (refactoring); difficult to revert the fix without losing the refactoring or vice versa; increases hotfix risk
|
|
48
|
+
- **Fix**: Separate refactoring commits from fix commits completely; in hotfix scenarios, fix first, refactor later in a dedicated branch
|
|
49
|
+
|
|
50
|
+
### 8. Copy-Paste Refactoring
|
|
51
|
+
- **Problem**: "Refactoring" by duplicating code and modifying the copy instead of restructuring the original; creating a "v2" method alongside the original
|
|
52
|
+
- **Consequences**: Doubles the maintenance burden; the original is never removed; two diverging implementations of the same logic
|
|
53
|
+
- **Fix**: Use Extract Method/Class to share common logic; migrate callers incrementally to the new structure; remove the old code once all callers are migrated
|
|
54
|
+
|
|
55
|
+
## Design Anti-Patterns
|
|
56
|
+
|
|
57
|
+
### 9. Speculative Generalization in Refactoring
|
|
58
|
+
- **Problem**: Adding extension points, plugin architectures, or configuration options "in case we need them later" during a refactoring session
|
|
59
|
+
- **Consequences**: YAGNI violation; increased code surface area with no current users; maintenance cost for unused abstractions; the predicted future need often does not materialize or looks different than expected
|
|
60
|
+
- **Fix**: Refactor only to address current, concrete problems; optimize for readability and simplicity today; add extension points when an actual second use case arrives
|
|
61
|
+
|
|
62
|
+
### 10. Inheritance Over Composition
|
|
63
|
+
- **Problem**: Refactoring duplication by creating deep inheritance hierarchies instead of using composition and delegation
|
|
64
|
+
- **Consequences**: Fragile base class problem; tight coupling between parent and children; DIT (depth of inheritance tree) exceeds 3-4; Liskov Substitution violations; difficulty understanding behavior without reading the entire hierarchy
|
|
65
|
+
- **Fix**: Prefer composition and delegation; use interfaces to define contracts; extract shared behavior into composed helper objects rather than base classes; limit inheritance depth to 2-3 levels
|
|
66
|
+
|
|
67
|
+
### 11. Over-Decomposition
|
|
68
|
+
- **Problem**: Breaking code into extremely small methods (1-3 lines) or extremely small classes (single method) in pursuit of SRP purity
|
|
69
|
+
- **Consequences**: Reading the code requires following 15+ method calls to understand a single operation; debugger stepping becomes painful; the "where is the logic?" problem; increased indirection without improved clarity
|
|
70
|
+
- **Fix**: Methods should be small but semantically complete — a method should perform one complete thought, not one line of code; aim for 5-15 lines per method as a sweet spot; group closely related operations
|
|
71
|
+
|
|
72
|
+
### 12. Refactoring Toward the Wrong Abstraction
|
|
73
|
+
- **Problem**: Refactoring code to match a textbook pattern or architecture that does not fit the actual domain or usage patterns
|
|
74
|
+
- **Consequences**: Impedance mismatch between code structure and domain logic; forced workarounds; worse readability than the original
|
|
75
|
+
- **Fix**: Let the domain drive the abstraction; study how the code is actually used before choosing a target structure; validate the target design with concrete use cases before transforming
|
|
76
|
+
|
|
77
|
+
## Process Anti-Patterns
|
|
78
|
+
|
|
79
|
+
### 13. Solo Refactoring of Shared Code
|
|
80
|
+
- **Problem**: Refactoring heavily-used shared code (utilities, core libraries, data models) without consulting the team
|
|
81
|
+
- **Consequences**: Breaks other team members' work; merge conflicts across multiple branches; API changes that callers did not expect
|
|
82
|
+
- **Fix**: Discuss significant refactorings in code review or team standup before starting; for shared code, create a migration plan; deprecate old APIs before removing them; provide a migration guide
|
|
83
|
+
|
|
84
|
+
### 14. Refactoring Under Time Pressure
|
|
85
|
+
- **Problem**: Attempting significant refactoring during a release crunch, sprint end, or incident response
|
|
86
|
+
- **Consequences**: Incomplete refactoring committed under pressure; half-refactored code is worse than the original; increased risk of production incidents
|
|
87
|
+
- **Fix**: Time-box all refactoring; if the scope cannot fit the available time, defer it; never force-merge an incomplete refactoring
|
|
88
|
+
|
|
89
|
+
### 15. Ignoring Performance During Refactoring
|
|
90
|
+
- **Problem**: Assuming that any behavior-preserving transformation is also performance-preserving
|
|
91
|
+
- **Consequences**: Extract Method may cause additional function call overhead in hot loops; replacing direct access with getter chains may cause cache misses; introducing polymorphism where JIT was inlining direct calls
|
|
92
|
+
- **Fix**: Profile performance-critical code before and after refactoring; for hot paths, benchmark with realistic data; acceptable regression threshold: < 5% for hot paths, < 10% for non-critical paths
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
domain: refactor
|
|
3
|
+
topic: refactoring-best-practices
|
|
4
|
+
priority: high
|
|
5
|
+
ttl: 30d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Code Refactoring — Best Practices
|
|
9
|
+
|
|
10
|
+
## Incremental Refactoring
|
|
11
|
+
|
|
12
|
+
### 1. Small, Reversible Steps
|
|
13
|
+
- Each refactoring step should be a single, well-defined transformation (one Extract Method, one Move Field, one Rename)
|
|
14
|
+
- Every step must be independently compilable and testable — never leave code in a broken state between steps
|
|
15
|
+
- Maintain a rollback point before each transformation — use version control commits as checkpoints
|
|
16
|
+
- If a step takes more than 15 minutes without a green test suite, the step is too large — decompose further
|
|
17
|
+
|
|
18
|
+
### 2. The Refactoring Cycle
|
|
19
|
+
```
|
|
20
|
+
Red (failing test, if adding coverage) → Green (make it pass) → Refactor (improve structure) → Green (verify equivalence) → Commit
|
|
21
|
+
```
|
|
22
|
+
- Never refactor red code — always start from a passing test suite
|
|
23
|
+
- After each refactoring step, run the full relevant test suite before proceeding
|
|
24
|
+
- Commit after each successful step to create a rollback point
|
|
25
|
+
|
|
26
|
+
### 3. Prioritize by Impact
|
|
27
|
+
Rank refactoring candidates using this priority matrix:
|
|
28
|
+
|
|
29
|
+
| Priority | Criteria | Example |
|
|
30
|
+
|----------|----------|---------|
|
|
31
|
+
| P0 — Critical | Blocks feature development or causes bugs | Circular dependency preventing deployment |
|
|
32
|
+
| P1 — High | High complexity (CC > 20) in frequently modified code | God class edited in every sprint |
|
|
33
|
+
| P2 — Medium | Code smells in stable code with moderate complexity | Duplicate code in rarely-changed modules |
|
|
34
|
+
| P3 — Low | Cosmetic improvements, naming, formatting | Inconsistent naming conventions |
|
|
35
|
+
|
|
36
|
+
Focus on code that is **both complex and frequently changed** (high churn + high complexity = refactoring priority).
|
|
37
|
+
|
|
38
|
+
### 4. Scope Control
|
|
39
|
+
- Define a clear refactoring boundary before starting — which files/classes/methods are in scope
|
|
40
|
+
- Resist the urge to "fix one more thing" outside the defined scope
|
|
41
|
+
- Track discovered issues outside scope as separate refactoring tasks for later
|
|
42
|
+
- Time-box refactoring sessions: 30-90 minutes per focused refactoring session
|
|
43
|
+
|
|
44
|
+
## Test-Driven Refactoring
|
|
45
|
+
|
|
46
|
+
### 1. Characterization Tests
|
|
47
|
+
Before refactoring code that lacks tests:
|
|
48
|
+
- Write **characterization tests** that capture the current behavior, including edge cases
|
|
49
|
+
- Execute the code with various inputs and assert the actual outputs (even if they seem wrong)
|
|
50
|
+
- These tests serve as a behavioral contract — they should pass both before and after refactoring
|
|
51
|
+
- Cover at minimum: happy path, boundary values, null/empty inputs, error paths
|
|
52
|
+
|
|
53
|
+
### 2. Test Coverage Requirements
|
|
54
|
+
Before beginning a refactoring session:
|
|
55
|
+
- Verify that the code under refactoring has at least **80% line coverage** and **70% branch coverage**
|
|
56
|
+
- If coverage is insufficient, write additional tests BEFORE refactoring
|
|
57
|
+
- Pay special attention to conditional branches — each branch of an if/else, each case in a switch
|
|
58
|
+
- For extracted methods: ensure the original tests still exercise the extracted code through the caller
|
|
59
|
+
|
|
60
|
+
### 3. Mutation Testing Awareness
|
|
61
|
+
- After refactoring, consider whether the test suite would catch regressions introduced by common errors:
|
|
62
|
+
- Off-by-one errors in extracted boundary logic
|
|
63
|
+
- Inverted boolean conditions
|
|
64
|
+
- Missing null checks after moving code
|
|
65
|
+
- Changed evaluation order in extracted expressions
|
|
66
|
+
- If any mutation would go undetected, add targeted tests
|
|
67
|
+
|
|
68
|
+
### 4. Test Refactoring
|
|
69
|
+
- Tests themselves may need refactoring — but refactor tests and production code separately, never simultaneously
|
|
70
|
+
- When extracting a class, create a new test class for it; keep original tests as integration tests
|
|
71
|
+
- Use the same incremental approach for test refactoring: one step at a time, verify passing after each step
|
|
72
|
+
|
|
73
|
+
## Equivalence Verification
|
|
74
|
+
|
|
75
|
+
### 1. Behavioral Equivalence Checklist
|
|
76
|
+
After each refactoring step, verify:
|
|
77
|
+
- [ ] All existing tests pass without modification
|
|
78
|
+
- [ ] Public method signatures are unchanged (names, parameters, return types)
|
|
79
|
+
- [ ] Exception/error behavior is preserved (same exceptions for same invalid inputs)
|
|
80
|
+
- [ ] Side effects are preserved (same writes, same external calls, same logging)
|
|
81
|
+
- [ ] Concurrency behavior is preserved (thread safety, locking semantics, ordering)
|
|
82
|
+
- [ ] Performance characteristics are within acceptable bounds (no O(n) to O(n^2) regressions)
|
|
83
|
+
|
|
84
|
+
### 2. Contract-Based Verification
|
|
85
|
+
For each public method under refactoring, document:
|
|
86
|
+
- **Preconditions**: What must be true before the method is called (parameter constraints, object state)
|
|
87
|
+
- **Postconditions**: What must be true after the method returns (return value properties, state changes)
|
|
88
|
+
- **Invariants**: What must always be true about the object (field relationships, consistency rules)
|
|
89
|
+
- Verify that all three are preserved after refactoring
|
|
90
|
+
|
|
91
|
+
### 3. Snapshot Testing
|
|
92
|
+
For complex transformations:
|
|
93
|
+
- Record input/output pairs from the original code for a comprehensive set of scenarios
|
|
94
|
+
- After refactoring, replay the same inputs and compare outputs byte-for-byte
|
|
95
|
+
- This is especially valuable for functions with complex output (serialization, formatting, rendering)
|
|
96
|
+
|
|
97
|
+
### 4. Integration Point Verification
|
|
98
|
+
When refactoring code that interacts with external systems:
|
|
99
|
+
- Verify that API call patterns are unchanged (same endpoints, same payloads, same headers)
|
|
100
|
+
- Verify that database queries produce the same results
|
|
101
|
+
- Verify that message queue interactions are preserved (same topics, same message formats)
|
|
102
|
+
- Run integration tests if available; if not, document the integration contracts
|
|
103
|
+
|
|
104
|
+
## Code Quality Measurement
|
|
105
|
+
|
|
106
|
+
### 1. Before/After Metrics
|
|
107
|
+
Always measure and report:
|
|
108
|
+
- **Cyclomatic Complexity**: Per-method and per-class, before and after
|
|
109
|
+
- **Cognitive Complexity**: Per-method, before and after
|
|
110
|
+
- **Coupling**: Afferent and efferent, before and after
|
|
111
|
+
- **Duplication**: Lines/blocks of duplicate code, before and after
|
|
112
|
+
- **Lines of Code**: Per-method and per-class (with context — shorter is not always better)
|
|
113
|
+
|
|
114
|
+
### 2. Quality Gates
|
|
115
|
+
A refactoring is considered successful when:
|
|
116
|
+
- All tests pass (mandatory — non-negotiable)
|
|
117
|
+
- Cyclomatic complexity of target methods is reduced by at least 20%
|
|
118
|
+
- No new code smells are introduced (verified by static analysis)
|
|
119
|
+
- Code review indicates improved readability
|
|
120
|
+
- No performance regressions beyond 5% in hot paths
|
|
121
|
+
|
|
122
|
+
### 3. Static Analysis Integration
|
|
123
|
+
Leverage static analysis tools to validate improvements:
|
|
124
|
+
- Run linter before and after to compare violation counts
|
|
125
|
+
- Check for new warnings introduced by the refactoring
|
|
126
|
+
- Validate that type safety is preserved or improved
|
|
127
|
+
- Ensure no new accessibility or security issues are introduced
|
|
128
|
+
|
|
129
|
+
## Communication and Documentation
|
|
130
|
+
|
|
131
|
+
### 1. Refactoring Commit Messages
|
|
132
|
+
Structure commit messages for refactoring:
|
|
133
|
+
```
|
|
134
|
+
refactor(<scope>): <what was changed>
|
|
135
|
+
|
|
136
|
+
- Why: <smell or metric that triggered the refactoring>
|
|
137
|
+
- How: <technique applied (e.g., Extract Method, Replace with Strategy)>
|
|
138
|
+
- Metrics: <before/after complexity, coupling, or duplication numbers>
|
|
139
|
+
- Equivalence: <how behavioral equivalence was verified>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 2. Decision Records
|
|
143
|
+
For significant refactorings (pattern introductions, architecture changes):
|
|
144
|
+
- Document the problem that triggered the refactoring
|
|
145
|
+
- List alternatives considered and why the chosen approach was selected
|
|
146
|
+
- Record the expected and actual quality improvements
|
|
147
|
+
- Note any trade-offs or known limitations of the new design
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
domain: refactor
|
|
3
|
+
topic: refactoring-catalog-patterns-principles
|
|
4
|
+
priority: high
|
|
5
|
+
ttl: 90d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Code Refactoring — Domain Knowledge
|
|
9
|
+
|
|
10
|
+
## Martin Fowler's Refactoring Catalog
|
|
11
|
+
|
|
12
|
+
### Code Smells — Detection Signatures
|
|
13
|
+
|
|
14
|
+
#### Bloaters
|
|
15
|
+
- **Long Method** — Method exceeds 20 lines or has more than 3 levels of nesting; contains inline comments explaining "sections" of logic
|
|
16
|
+
- **Large Class / God Class** — Class has more than 10 public methods, more than 20 fields, or handles 3+ distinct responsibilities
|
|
17
|
+
- **Primitive Obsession** — Uses primitive types (string, int, boolean) to represent domain concepts (e.g., `string email` instead of `Email` type; `int status` instead of `Status` enum)
|
|
18
|
+
- **Long Parameter List** — Method takes more than 3-4 parameters; parameter groups travel together across methods
|
|
19
|
+
- **Data Clumps** — The same group of 3+ variables appears together in multiple places (e.g., `street`, `city`, `zip` always appear as a group)
|
|
20
|
+
|
|
21
|
+
#### Object-Orientation Abusers
|
|
22
|
+
- **Switch Statements** — Repeated switch/if-else chains on the same type field, especially when adding a new case requires changes in multiple locations
|
|
23
|
+
- **Temporary Field** — Object fields that are only set and used in certain circumstances, remaining null/undefined otherwise
|
|
24
|
+
- **Refused Bequest** — Subclass uses only a small portion of inherited methods/properties, or overrides most of them to do nothing
|
|
25
|
+
- **Parallel Inheritance Hierarchies** — Every time you add a subclass to one hierarchy, you must add a corresponding subclass to another
|
|
26
|
+
|
|
27
|
+
#### Change Preventers
|
|
28
|
+
- **Divergent Change** — A single class is modified for multiple unrelated reasons; different groups of changes affect different methods
|
|
29
|
+
- **Shotgun Surgery** — A single logical change requires small modifications scattered across many classes
|
|
30
|
+
- **Feature Envy** — A method accesses data from another object more than from its own object; it "wants to be" in the other class
|
|
31
|
+
|
|
32
|
+
#### Dispensables
|
|
33
|
+
- **Duplicate Code** — Identical or near-identical code structures in 2+ locations; includes structural duplication (same logic with different variable names)
|
|
34
|
+
- **Dead Code** — Unreachable methods, unused variables, obsolete commented-out code, never-true conditionals
|
|
35
|
+
- **Lazy Class** — A class that does too little to justify its existence; has only 1-2 trivial methods
|
|
36
|
+
- **Speculative Generality** — Abstract classes, interfaces, or parameters that exist "just in case" but currently have only one implementation
|
|
37
|
+
|
|
38
|
+
#### Couplers
|
|
39
|
+
- **Inappropriate Intimacy** — Two classes access each other's private members or internal details excessively
|
|
40
|
+
- **Message Chains** — Long chains of method calls: `a.getB().getC().getD().doSomething()` (Law of Demeter violations)
|
|
41
|
+
- **Middle Man** — A class that delegates almost all its work to another class, adding no value
|
|
42
|
+
|
|
43
|
+
### Refactoring Techniques — By Smell
|
|
44
|
+
|
|
45
|
+
| Smell | Primary Refactoring | Secondary Refactoring |
|
|
46
|
+
|-------|--------------------|-----------------------|
|
|
47
|
+
| Long Method | Extract Method | Replace Temp with Query, Decompose Conditional |
|
|
48
|
+
| Large Class | Extract Class | Extract Subclass, Extract Interface |
|
|
49
|
+
| Primitive Obsession | Replace Primitive with Object | Introduce Parameter Object, Replace Type Code with Subclass |
|
|
50
|
+
| Long Parameter List | Introduce Parameter Object | Preserve Whole Object, Replace Parameter with Method Call |
|
|
51
|
+
| Data Clumps | Extract Class | Introduce Parameter Object |
|
|
52
|
+
| Switch Statements | Replace Conditional with Polymorphism | Replace Type Code with Strategy, Introduce Null Object |
|
|
53
|
+
| Duplicate Code | Extract Method | Pull Up Method, Form Template Method |
|
|
54
|
+
| Feature Envy | Move Method | Move Field, Extract Method + Move |
|
|
55
|
+
| Shotgun Surgery | Move Method + Move Field | Inline Class (consolidate) |
|
|
56
|
+
| Divergent Change | Extract Class | Extract Module |
|
|
57
|
+
| Message Chains | Hide Delegate | Extract Method, Move Method |
|
|
58
|
+
| Middle Man | Remove Middle Man | Inline Method, Replace Delegation with Inheritance |
|
|
59
|
+
| Dead Code | Remove Dead Code | — |
|
|
60
|
+
| Lazy Class | Inline Class | Collapse Hierarchy |
|
|
61
|
+
| Speculative Generality | Collapse Hierarchy | Inline Class, Remove Parameter |
|
|
62
|
+
|
|
63
|
+
## Gang of Four (GoF) Design Patterns
|
|
64
|
+
|
|
65
|
+
### Creational Patterns
|
|
66
|
+
|
|
67
|
+
#### Factory Method
|
|
68
|
+
- **Problem it solves**: Client code coupled to concrete class constructors; adding new types requires modifying client code
|
|
69
|
+
- **When to apply**: Multiple related classes with a common interface; object creation logic is complex or conditional
|
|
70
|
+
- **Structure**: Abstract creator declares factory method; concrete creators override it to produce specific products
|
|
71
|
+
- **Refactoring trigger**: `new` keyword appears in switch/if-else chains; constructor calls scattered across codebase
|
|
72
|
+
|
|
73
|
+
#### Abstract Factory
|
|
74
|
+
- **Problem it solves**: Families of related objects that must be created together; switching between families requires changing multiple creation points
|
|
75
|
+
- **When to apply**: Multiple product families (e.g., UI themes, database backends); products within a family must be compatible
|
|
76
|
+
- **Refactoring trigger**: Parallel switch statements creating different but related objects
|
|
77
|
+
|
|
78
|
+
#### Builder
|
|
79
|
+
- **Problem it solves**: Complex object construction with many optional parameters; telescoping constructor anti-pattern
|
|
80
|
+
- **When to apply**: Object requires 5+ configuration parameters; construction steps may vary
|
|
81
|
+
- **Refactoring trigger**: Constructors with 5+ parameters; multiple constructor overloads
|
|
82
|
+
|
|
83
|
+
#### Singleton
|
|
84
|
+
- **Problem it solves**: Exactly one instance needed globally with a single access point
|
|
85
|
+
- **When to apply**: Resource managers, configuration, logging (use sparingly; often an anti-pattern itself)
|
|
86
|
+
- **Refactoring trigger**: Global variables; static utility classes with state
|
|
87
|
+
|
|
88
|
+
### Structural Patterns
|
|
89
|
+
|
|
90
|
+
#### Adapter
|
|
91
|
+
- **Problem it solves**: Incompatible interfaces between existing classes; integrating third-party code with different API conventions
|
|
92
|
+
- **When to apply**: Wrapping legacy code; integrating external libraries; bridging interface mismatches
|
|
93
|
+
- **Refactoring trigger**: Wrapper functions that translate between two interface styles
|
|
94
|
+
|
|
95
|
+
#### Decorator
|
|
96
|
+
- **Problem it solves**: Need to add responsibilities to objects dynamically without modifying their class; combinatorial explosion of subclasses
|
|
97
|
+
- **When to apply**: Cross-cutting concerns (logging, caching, validation); optional behaviors that can be composed
|
|
98
|
+
- **Refactoring trigger**: Subclass explosion from combinations of features; repeated wrapper logic
|
|
99
|
+
|
|
100
|
+
#### Facade
|
|
101
|
+
- **Problem it solves**: Complex subsystem with many interdependent classes; client code needs a simplified interface
|
|
102
|
+
- **When to apply**: Simplifying access to a library; providing a high-level API over low-level operations
|
|
103
|
+
- **Refactoring trigger**: Client code repeatedly uses the same sequence of subsystem calls
|
|
104
|
+
|
|
105
|
+
#### Composite
|
|
106
|
+
- **Problem it solves**: Tree structures where individual objects and compositions should be treated uniformly
|
|
107
|
+
- **When to apply**: File systems, UI hierarchies, organizational structures, expression trees
|
|
108
|
+
- **Refactoring trigger**: Recursive structures with duplicated traversal logic; type-checking for leaf vs. container
|
|
109
|
+
|
|
110
|
+
### Behavioral Patterns
|
|
111
|
+
|
|
112
|
+
#### Strategy
|
|
113
|
+
- **Problem it solves**: Multiple algorithms for the same task; algorithm selection via switch/if-else chains
|
|
114
|
+
- **When to apply**: Sorting algorithms, pricing strategies, validation rules, rendering modes
|
|
115
|
+
- **Refactoring trigger**: Switch statements selecting behavior; conditional logic that varies by "type" or "mode"
|
|
116
|
+
|
|
117
|
+
#### Observer
|
|
118
|
+
- **Problem it solves**: Objects need to be notified of state changes in another object without tight coupling
|
|
119
|
+
- **When to apply**: Event systems, data binding, pub/sub patterns, UI updates from model changes
|
|
120
|
+
- **Refactoring trigger**: Explicit notification calls scattered through setter methods; polling for changes
|
|
121
|
+
|
|
122
|
+
#### Command
|
|
123
|
+
- **Problem it solves**: Need to parameterize, queue, log, or undo operations; decouple invoker from executor
|
|
124
|
+
- **When to apply**: Undo/redo systems, task queues, macro recording, transaction management
|
|
125
|
+
- **Refactoring trigger**: Methods that both decide what to do and do it; no support for undo
|
|
126
|
+
|
|
127
|
+
#### Template Method
|
|
128
|
+
- **Problem it solves**: Algorithm structure is shared but individual steps vary across subclasses
|
|
129
|
+
- **When to apply**: Framework hooks, processing pipelines, lifecycle methods
|
|
130
|
+
- **Refactoring trigger**: Duplicate code in sibling classes with small step-level variations
|
|
131
|
+
|
|
132
|
+
#### State
|
|
133
|
+
- **Problem it solves**: Object behavior changes based on internal state; large switch/if-else on state variable
|
|
134
|
+
- **When to apply**: Workflow engines, protocol handlers, UI components with multiple modes
|
|
135
|
+
- **Refactoring trigger**: Methods with large switch statements on a state field; state transitions scattered across methods
|
|
136
|
+
|
|
137
|
+
## SOLID Principles
|
|
138
|
+
|
|
139
|
+
### Single Responsibility Principle (SRP)
|
|
140
|
+
- **Definition**: A class should have only one reason to change — one responsibility, one actor it serves
|
|
141
|
+
- **Violation indicators**: Class name includes "And" or "Manager" or "Handler" for unrelated concerns; class changes for multiple unrelated feature requests; class has methods operating on different data domains
|
|
142
|
+
- **Refactoring**: Extract Class — split the class along responsibility boundaries; each resulting class serves one actor
|
|
143
|
+
|
|
144
|
+
### Open/Closed Principle (OCP)
|
|
145
|
+
- **Definition**: Software entities should be open for extension but closed for modification
|
|
146
|
+
- **Violation indicators**: Adding a new feature requires modifying existing working code; switch/if-else chains on type discriminators grow with each new variant
|
|
147
|
+
- **Refactoring**: Replace Conditional with Polymorphism; introduce Strategy or Template Method pattern; use dependency injection
|
|
148
|
+
|
|
149
|
+
### Liskov Substitution Principle (LSP)
|
|
150
|
+
- **Definition**: Subtypes must be substitutable for their base types without altering program correctness
|
|
151
|
+
- **Violation indicators**: Subclass overrides a method to throw "not supported" exceptions; subclass weakens preconditions or strengthens postconditions; client code checks `instanceof` before calling methods
|
|
152
|
+
- **Refactoring**: Extract Interface for the true shared contract; use composition over inheritance; restructure hierarchy
|
|
153
|
+
|
|
154
|
+
### Interface Segregation Principle (ISP)
|
|
155
|
+
- **Definition**: Clients should not be forced to depend on methods they do not use
|
|
156
|
+
- **Violation indicators**: Interface has 10+ methods; implementing classes leave many methods as no-ops or throw exceptions; "fat" interfaces with unrelated method groups
|
|
157
|
+
- **Refactoring**: Split into focused interfaces (e.g., `Readable`, `Writable` instead of `ReadWritable`); use role interfaces
|
|
158
|
+
|
|
159
|
+
### Dependency Inversion Principle (DIP)
|
|
160
|
+
- **Definition**: High-level modules should not depend on low-level modules; both should depend on abstractions
|
|
161
|
+
- **Violation indicators**: High-level business logic imports and instantiates concrete infrastructure classes (database drivers, HTTP clients); no interfaces between layers
|
|
162
|
+
- **Refactoring**: Extract Interface for dependencies; introduce constructor injection or service locator; use Factory for object creation
|
|
163
|
+
|
|
164
|
+
## Complexity Metrics
|
|
165
|
+
|
|
166
|
+
### Cyclomatic Complexity (McCabe)
|
|
167
|
+
- **Definition**: Number of linearly independent paths through a function; calculated as `E - N + 2P` (edges - nodes + 2 * connected components) in the control flow graph
|
|
168
|
+
- **Practical calculation**: Count 1 (base) + 1 for each `if`, `else if`, `for`, `while`, `case`, `catch`, `&&`, `||`, `?:`
|
|
169
|
+
- **Thresholds**: 1-10 = simple/low risk; 11-20 = moderate complexity; 21-50 = high complexity/refactor recommended; 50+ = untestable/must refactor
|
|
170
|
+
- **Reduction techniques**: Extract Method, Replace Conditional with Polymorphism, Decompose Conditional, Replace Nested Conditional with Guard Clauses
|
|
171
|
+
|
|
172
|
+
### Cognitive Complexity (SonarSource)
|
|
173
|
+
- **Definition**: Measures how difficult code is for a human to understand; penalizes nesting, breaks in linear flow, and recursion
|
|
174
|
+
- **Key differences from cyclomatic**: Nesting increments penalty (nested `if` costs more than sequential `if`); `else` and `switch` cases are counted; shorthand syntax is not penalized
|
|
175
|
+
- **Thresholds**: 0-5 = easy to understand; 6-15 = moderate; 16-25 = difficult; 25+ = very difficult/refactor required
|
|
176
|
+
|
|
177
|
+
### Coupling Metrics
|
|
178
|
+
- **Afferent Coupling (Ca)**: Number of external classes that depend on this class — high Ca means the class is heavily used and changes are risky
|
|
179
|
+
- **Efferent Coupling (Ce)**: Number of external classes this class depends on — high Ce means the class is fragile (many reasons to change)
|
|
180
|
+
- **Instability (I)**: `Ce / (Ca + Ce)` — ranges from 0 (maximally stable) to 1 (maximally unstable)
|
|
181
|
+
- **Abstractness (A)**: Ratio of abstract classes/interfaces to total classes in a package
|
|
182
|
+
- **Distance from Main Sequence (D)**: `|A + I - 1|` — measures balance; 0 is ideal; high values indicate the "zone of pain" (stable + concrete) or "zone of uselessness" (unstable + abstract)
|
|
183
|
+
|
|
184
|
+
### Depth of Inheritance Tree (DIT)
|
|
185
|
+
- **Definition**: Maximum length from a class to the root of its inheritance hierarchy
|
|
186
|
+
- **Thresholds**: 0-2 = good; 3-4 = acceptable; 5+ = excessive inheritance/consider composition
|
|
187
|
+
- **Risks of deep inheritance**: Increased fragility, difficulty understanding behavior, tight coupling to ancestor implementations
|
|
188
|
+
|
|
189
|
+
### Lines of Code (LOC) Guidelines
|
|
190
|
+
- **Method**: Aim for under 20 lines; extract at 30+
|
|
191
|
+
- **Class**: Aim for under 200 lines; extract at 400+
|
|
192
|
+
- **File**: Aim for under 400 lines; split at 600+
|
|
193
|
+
- **Note**: LOC is a coarse metric — always combine with complexity metrics for accurate assessment
|
package/manifest.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@botlearn/refactor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Automated code refactoring with design pattern application, complexity reduction, and behavioral equivalence verification for OpenClaw Agent",
|
|
5
|
+
"category": "programming-assistance",
|
|
6
|
+
"author": "BotLearn",
|
|
7
|
+
"benchmarkDimension": "code-generation",
|
|
8
|
+
"expectedImprovement": 40,
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@botlearn/code-review": "^1.0.0"
|
|
11
|
+
},
|
|
12
|
+
"compatibility": {
|
|
13
|
+
"openclaw": ">=0.5.0"
|
|
14
|
+
},
|
|
15
|
+
"files": {
|
|
16
|
+
"skill": "skill.md",
|
|
17
|
+
"knowledge": [
|
|
18
|
+
"knowledge/domain.md",
|
|
19
|
+
"knowledge/best-practices.md",
|
|
20
|
+
"knowledge/anti-patterns.md"
|
|
21
|
+
],
|
|
22
|
+
"strategies": [
|
|
23
|
+
"strategies/main.md"
|
|
24
|
+
],
|
|
25
|
+
"smokeTest": "tests/smoke.json",
|
|
26
|
+
"benchmark": "tests/benchmark.json"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@botlearn/refactor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Automated code refactoring with design pattern application, complexity reduction, and behavioral equivalence verification for OpenClaw Agent",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "manifest.json",
|
|
7
|
+
"files": [
|
|
8
|
+
"manifest.json",
|
|
9
|
+
"skill.md",
|
|
10
|
+
"knowledge/",
|
|
11
|
+
"strategies/",
|
|
12
|
+
"tests/",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"botlearn",
|
|
17
|
+
"openclaw",
|
|
18
|
+
"skill",
|
|
19
|
+
"programming-assistance"
|
|
20
|
+
],
|
|
21
|
+
"author": "BotLearn",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@botlearn/code-review": "0.1.0"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/readai-team/botlearn-awesome-skills.git",
|
|
29
|
+
"directory": "packages/skills/refactor"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/readai-team/botlearn-awesome-skills/tree/main/packages/skills/refactor",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/readai-team/botlearn-awesome-skills/issues"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
}
|
|
38
|
+
}
|
package/skill.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refactor
|
|
3
|
+
role: Code Refactoring Specialist
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
triggers:
|
|
6
|
+
- "refactor"
|
|
7
|
+
- "clean up code"
|
|
8
|
+
- "improve code quality"
|
|
9
|
+
- "apply design pattern"
|
|
10
|
+
- "reduce complexity"
|
|
11
|
+
- "simplify code"
|
|
12
|
+
- "restructure code"
|
|
13
|
+
- "reduce duplication"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Role
|
|
17
|
+
|
|
18
|
+
You are a Code Refactoring Specialist. When activated, you analyze existing code to identify structural weaknesses, code smells, and complexity hotspots, then apply systematic refactoring transformations that improve readability, maintainability, and design quality while preserving exact behavioral equivalence.
|
|
19
|
+
|
|
20
|
+
# Capabilities
|
|
21
|
+
|
|
22
|
+
1. Detect code smells using Martin Fowler's refactoring catalog — including Long Method, God Class, Feature Envy, Data Clumps, Primitive Obsession, Shotgun Surgery, Divergent Change, and Parallel Inheritance Hierarchies
|
|
23
|
+
2. Apply Gang of Four (GoF) design patterns where they resolve identified structural problems — Strategy, Observer, Factory, Decorator, Command, Template Method, State, and Composite
|
|
24
|
+
3. Enforce SOLID principles through targeted transformations — extract interfaces for Dependency Inversion, split classes for Single Responsibility, introduce polymorphism for Open/Closed
|
|
25
|
+
4. Measure and reduce cyclomatic complexity, cognitive complexity, coupling metrics (afferent/efferent), and depth of inheritance through systematic decomposition
|
|
26
|
+
5. Verify behavioral equivalence after each transformation step using input/output contract analysis, test suite validation, and invariant checking
|
|
27
|
+
6. Generate refactoring plans with dependency-ordered steps, estimated risk levels, and rollback points
|
|
28
|
+
|
|
29
|
+
# Constraints
|
|
30
|
+
|
|
31
|
+
1. Never change observable behavior — all refactoring must be strictly behavior-preserving; if a transformation could alter semantics, flag it and request confirmation
|
|
32
|
+
2. Never refactor without an existing test suite or a plan to create one — tests are the safety net that guarantees equivalence
|
|
33
|
+
3. Never apply a design pattern solely because it exists — patterns must solve a concrete structural problem identified in the code
|
|
34
|
+
4. Never perform large-scale refactoring in a single step — always decompose into incremental, independently verifiable transformations
|
|
35
|
+
5. Never increase complexity to satisfy a pattern — if the refactored code is harder to understand than the original, the refactoring is wrong
|
|
36
|
+
6. Always preserve public API contracts — method signatures, return types, and error behavior visible to callers must remain unchanged unless explicitly agreed
|
|
37
|
+
|
|
38
|
+
# Activation
|
|
39
|
+
|
|
40
|
+
WHEN the user requests code refactoring, quality improvement, or design pattern application:
|
|
41
|
+
1. Invoke @botlearn/code-review to perform initial code analysis and identify quality issues
|
|
42
|
+
2. Detect code smells and structural problems using knowledge/domain.md
|
|
43
|
+
3. Match identified problems to appropriate refactoring techniques and design patterns
|
|
44
|
+
4. Generate a step-by-step refactoring plan following strategies/main.md
|
|
45
|
+
5. Validate the plan against knowledge/best-practices.md for incremental safety
|
|
46
|
+
6. Check the plan against knowledge/anti-patterns.md to avoid common refactoring mistakes
|
|
47
|
+
7. Execute transformations incrementally with equivalence verification at each step
|
|
48
|
+
8. Measure quality improvement using complexity metrics and report the delta
|