skills/mw-mr-mf/SKILL.md
Iterative development workflow based on "Make it work, Make it right, Make it fast" philosophy. Use when building software features, components, or systems from scratch. Guides Claude through three distinct phases - getting a working solution first, then refactoring for quality, and finally optimizing performance only when needed. Prevents premature optimization and over-engineering. Integrates seamlessly with TDD (Test-Driven Development) by mapping test phases to development phases.
npx skillsauth add adrianbrowning/agent-skills jherr-dev-workflowInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
A systematic approach to building software iteratively, inspired by Jack Harrington (jherr) and the classic software development principle.
Development should happen in three distinct phases:
Each phase has different priorities and success criteria. Moving to the next phase too early causes problems.
Goal: Create a minimal working solution that demonstrates the feature works end-to-end.
Priorities:
With TDD (Test-Driven Development):
Without TDD:
Success criteria:
Common mistakes:
Goal: Refactor the working code into maintainable, well-structured software.
Priorities:
With TDD:
Without TDD:
Success criteria:
Common mistakes:
Goal: Optimize performance based on actual measured bottlenecks.
When to enter this phase:
Priorities:
With TDD:
Success criteria:
Common mistakes:
This workflow pairs naturally with Test-Driven Development:
How they complement each other:
Phase mapping:
Best practices:
If using TDD throughout:
Phase 1 - Make it work:
// Just get it working
function searchUsers(query: string) {
return users.filter(user =>
user.name.toLowerCase().includes(query.toLowerCase())
);
}
Phase 2 - Make it right:
// Add proper handling and structure
function searchUsers(query: string): User[] {
if (!query.trim()) return [];
const normalizedQuery = query.toLowerCase().trim();
return users.filter(user =>
user.name.toLowerCase().includes(normalizedQuery) ||
user.email.toLowerCase().includes(normalizedQuery)
);
}
Phase 3 - Make it fast (only if measurements show it's slow):
// Optimize with debouncing and indexing
const searchIndex = buildSearchIndex(users);
const debouncedSearch = debounce((query: string) => {
if (!query.trim()) return [];
const normalizedQuery = query.toLowerCase().trim();
return searchIndex.query(normalizedQuery);
}, 300);
Phase 1 - Make it work (with TDD):
// Test: Happy path only
test('adds item to cart', () => {
const cart = new ShoppingCart();
cart.addItem({ id: 1, name: 'Widget', price: 10 });
expect(cart.total()).toBe(10);
});
// Implementation: Simplest thing that works
class ShoppingCart {
items = [];
addItem(item) {
this.items.push(item);
}
total() {
return this.items.reduce((sum, item) => sum + item.price, 0);
}
}
Phase 2 - Make it right (with TDD):
// Tests: Add edge cases and error handling
test('handles empty cart', () => {
const cart = new ShoppingCart();
expect(cart.total()).toBe(0);
});
test('prevents adding invalid items', () => {
const cart = new ShoppingCart();
expect(() => cart.addItem(null)).toThrow();
});
test('removes items correctly', () => {
const cart = new ShoppingCart();
cart.addItem({ id: 1, name: 'Widget', price: 10 });
cart.removeItem(1);
expect(cart.total()).toBe(0);
});
// Implementation: Refactored with types and validation
interface CartItem {
id: number;
name: string;
price: number;
}
class ShoppingCart {
private items: CartItem[] = [];
addItem(item: CartItem): void {
if (!item || typeof item.price !== 'number') {
throw new Error('Invalid item');
}
this.items.push(item);
}
removeItem(id: number): void {
this.items = this.items.filter(item => item.id !== id);
}
total(): number {
return this.items.reduce((sum, item) => sum + item.price, 0);
}
}
Phase 3 - Make it fast (only if needed):
// Performance test
test('handles large cart efficiently', () => {
const cart = new ShoppingCart();
const start = performance.now();
for (let i = 0; i < 10000; i++) {
cart.addItem({ id: i, name: `Item ${i}`, price: i });
}
const total = cart.total();
const duration = performance.now() - start;
expect(duration).toBeLessThan(100); // Should complete in <100ms
expect(total).toBe(49995000);
});
// Optimized implementation with memoization
class ShoppingCart {
private items: CartItem[] = [];
private cachedTotal: number | null = null;
addItem(item: CartItem): void {
if (!item || typeof item.price !== 'number') {
throw new Error('Invalid item');
}
this.items.push(item);
this.cachedTotal = null; // Invalidate cache
}
total(): number {
if (this.cachedTotal !== null) {
return this.cachedTotal;
}
this.cachedTotal = this.items.reduce((sum, item) => sum + item.price, 0);
return this.cachedTotal;
}
}
This workflow may not fit when:
/tdd-integration - TDD Red-Green-Refactor cycle that complements this workflow/testing-best-practice - Testing philosophy and patterns for quality testsdevelopment
Best practices for TypeScript types, interfaces, assertions, and type safety. Use when writing or reviewing TypeScript code.
development
--- name: testing-best-practice description: A Skill for writing, reviewing, and refactoring tests using Artem-style principles: test intent over implementation, mock boundaries not internals, avoid flakiness, prefer integration tests, and use `using` for cleanup. --- # Testing Best Practice ## Instructions When the user asks for help with tests (writing new tests, improving existing ones, or defining testing standards), follow these rules: 1. **Test intent, not implementation** - Make te
development
Enforce Test-Driven Development with strict Red-Green-Refactor cycle using integration tests. Auto-triggers when implementing new features or functionality. Trigger phrases include "implement", "add feature", "build", "create functionality", or any request to add new behavior. Does NOT trigger for bug fixes, documentation, or configuration changes.
development
React Router v7 loader performance optimization techniques. Use when optimizing TTFB, eliminating waterfalls, consolidating database queries, or streaming secondary data in loaders. Triggers on "slow loaders", "optimize TTFB", "speed up React Router", "loader performance", or when loaders exceed 500ms response time.