@ruyfranca/myskills 1.0.27 → 1.0.29
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/.agent/skills/cqrs-implementation/SKILL.md +107 -0
- package/.agent/skills/ddd-strategic-design/SKILL.md +70 -0
- package/.agent/skills/ddd-tactical-patterns/SKILL.md +70 -0
- package/.agent/skills/elixir-pro/SKILL.md +89 -0
- package/.agent/skills/event-sourcing-architect/SKILL.md +66 -0
- package/.agent/skills/golang-pro/SKILL.md +121 -0
- package/.agent/skills/kotlin-coroutines-expert/SKILL.md +99 -0
- package/.agent/skills/modern-javascript-patterns/SKILL.md +131 -0
- package/.agent/skills/monorepo-architect/SKILL.md +91 -0
- package/.agent/skills/nextjs-react-expert/SKILL.md +94 -247
- package/.agent/skills/react-patterns/SKILL.md +200 -0
- package/.agent/skills/react-state-management/SKILL.md +147 -0
- package/.agent/skills/ruby-pro/SKILL.md +105 -0
- package/.agent/skills/zod-validation-expert/SKILL.md +132 -0
- package/README.md +41 -20
- package/package.json +1 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: react-patterns
|
|
3
|
+
description: "Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices."
|
|
4
|
+
risk: unknown
|
|
5
|
+
source: community
|
|
6
|
+
date_added: "2026-02-27"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# React Patterns
|
|
10
|
+
|
|
11
|
+
> Principles for building production-ready React applications.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. Component Design Principles
|
|
16
|
+
|
|
17
|
+
### Component Types
|
|
18
|
+
|
|
19
|
+
| Type | Use | State |
|
|
20
|
+
|------|-----|-------|
|
|
21
|
+
| **Server** | Data fetching, static | None |
|
|
22
|
+
| **Client** | Interactivity | useState, effects |
|
|
23
|
+
| **Presentational** | UI display | Props only |
|
|
24
|
+
| **Container** | Logic/state | Heavy state |
|
|
25
|
+
|
|
26
|
+
### Design Rules
|
|
27
|
+
|
|
28
|
+
- One responsibility per component
|
|
29
|
+
- Props down, events up
|
|
30
|
+
- Composition over inheritance
|
|
31
|
+
- Prefer small, focused components
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. Hook Patterns
|
|
36
|
+
|
|
37
|
+
### When to Extract Hooks
|
|
38
|
+
|
|
39
|
+
| Pattern | Extract When |
|
|
40
|
+
|---------|-------------|
|
|
41
|
+
| **useLocalStorage** | Same storage logic needed |
|
|
42
|
+
| **useDebounce** | Multiple debounced values |
|
|
43
|
+
| **useFetch** | Repeated fetch patterns |
|
|
44
|
+
| **useForm** | Complex form state |
|
|
45
|
+
|
|
46
|
+
### Hook Rules
|
|
47
|
+
|
|
48
|
+
- Hooks at top level only
|
|
49
|
+
- Same order every render
|
|
50
|
+
- Custom hooks start with "use"
|
|
51
|
+
- Clean up effects on unmount
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 3. State Management Selection
|
|
56
|
+
|
|
57
|
+
| Complexity | Solution |
|
|
58
|
+
|------------|----------|
|
|
59
|
+
| Simple | useState, useReducer |
|
|
60
|
+
| Shared local | Context |
|
|
61
|
+
| Server state | React Query, SWR |
|
|
62
|
+
| Complex global | Zustand, Redux Toolkit |
|
|
63
|
+
|
|
64
|
+
### State Placement
|
|
65
|
+
|
|
66
|
+
| Scope | Where |
|
|
67
|
+
|-------|-------|
|
|
68
|
+
| Single component | useState |
|
|
69
|
+
| Parent-child | Lift state up |
|
|
70
|
+
| Subtree | Context |
|
|
71
|
+
| App-wide | Global store |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 4. React 19 Patterns
|
|
76
|
+
|
|
77
|
+
### New Hooks
|
|
78
|
+
|
|
79
|
+
| Hook | Purpose |
|
|
80
|
+
|------|---------|
|
|
81
|
+
| **useActionState** | Form submission state |
|
|
82
|
+
| **useOptimistic** | Optimistic UI updates |
|
|
83
|
+
| **use** | Read resources in render |
|
|
84
|
+
|
|
85
|
+
### Compiler Benefits
|
|
86
|
+
|
|
87
|
+
- Automatic memoization
|
|
88
|
+
- Less manual useMemo/useCallback
|
|
89
|
+
- Focus on pure components
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 5. Composition Patterns
|
|
94
|
+
|
|
95
|
+
### Compound Components
|
|
96
|
+
|
|
97
|
+
- Parent provides context
|
|
98
|
+
- Children consume context
|
|
99
|
+
- Flexible slot-based composition
|
|
100
|
+
- Example: Tabs, Accordion, Dropdown
|
|
101
|
+
|
|
102
|
+
### Render Props vs Hooks
|
|
103
|
+
|
|
104
|
+
| Use Case | Prefer |
|
|
105
|
+
|----------|--------|
|
|
106
|
+
| Reusable logic | Custom hook |
|
|
107
|
+
| Render flexibility | Render props |
|
|
108
|
+
| Cross-cutting | Higher-order component |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 6. Performance Principles
|
|
113
|
+
|
|
114
|
+
### When to Optimize
|
|
115
|
+
|
|
116
|
+
| Signal | Action |
|
|
117
|
+
|--------|--------|
|
|
118
|
+
| Slow renders | Profile first |
|
|
119
|
+
| Large lists | Virtualize |
|
|
120
|
+
| Expensive calc | useMemo |
|
|
121
|
+
| Stable callbacks | useCallback |
|
|
122
|
+
|
|
123
|
+
### Optimization Order
|
|
124
|
+
|
|
125
|
+
1. Check if actually slow
|
|
126
|
+
2. Profile with DevTools
|
|
127
|
+
3. Identify bottleneck
|
|
128
|
+
4. Apply targeted fix
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 7. Error Handling
|
|
133
|
+
|
|
134
|
+
### Error Boundary Usage
|
|
135
|
+
|
|
136
|
+
| Scope | Placement |
|
|
137
|
+
|-------|-----------|
|
|
138
|
+
| App-wide | Root level |
|
|
139
|
+
| Feature | Route/feature level |
|
|
140
|
+
| Component | Around risky component |
|
|
141
|
+
|
|
142
|
+
### Error Recovery
|
|
143
|
+
|
|
144
|
+
- Show fallback UI
|
|
145
|
+
- Log error
|
|
146
|
+
- Offer retry option
|
|
147
|
+
- Preserve user data
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 8. TypeScript Patterns
|
|
152
|
+
|
|
153
|
+
### Props Typing
|
|
154
|
+
|
|
155
|
+
| Pattern | Use |
|
|
156
|
+
|---------|-----|
|
|
157
|
+
| Interface | Component props |
|
|
158
|
+
| Type | Unions, complex |
|
|
159
|
+
| Generic | Reusable components |
|
|
160
|
+
|
|
161
|
+
### Common Types
|
|
162
|
+
|
|
163
|
+
| Need | Type |
|
|
164
|
+
|------|------|
|
|
165
|
+
| Children | ReactNode |
|
|
166
|
+
| Event handler | MouseEventHandler |
|
|
167
|
+
| Ref | RefObject<Element> |
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 9. Testing Principles
|
|
172
|
+
|
|
173
|
+
| Level | Focus |
|
|
174
|
+
|-------|-------|
|
|
175
|
+
| Unit | Pure functions, hooks |
|
|
176
|
+
| Integration | Component behavior |
|
|
177
|
+
| E2E | User flows |
|
|
178
|
+
|
|
179
|
+
### Test Priorities
|
|
180
|
+
|
|
181
|
+
- User-visible behavior
|
|
182
|
+
- Edge cases
|
|
183
|
+
- Error states
|
|
184
|
+
- Accessibility
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 10. Anti-Patterns
|
|
189
|
+
|
|
190
|
+
| ❌ Don't | ✅ Do |
|
|
191
|
+
|----------|-------|
|
|
192
|
+
| Prop drilling deep | Use context |
|
|
193
|
+
| Giant components | Split smaller |
|
|
194
|
+
| useEffect for everything | Server components |
|
|
195
|
+
| Premature optimization | Profile first |
|
|
196
|
+
| Index as key | Stable unique ID |
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
> **Remember:** React is about composition. Build small, combine thoughtfully.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: react-state-management
|
|
3
|
+
description: "Comprehensive guide to modern React state management patterns, from local component state to global stores and server state synchronization."
|
|
4
|
+
risk: unknown
|
|
5
|
+
source: community
|
|
6
|
+
date_added: "2026-02-27"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# React State Management
|
|
10
|
+
|
|
11
|
+
Comprehensive guide to modern React state management patterns, from local component state to global stores and server state synchronization.
|
|
12
|
+
|
|
13
|
+
## Use this skill when
|
|
14
|
+
|
|
15
|
+
- Choosing the right state management solution
|
|
16
|
+
- Implementing Zustand, Redux Toolkit, Jotai, or React Query
|
|
17
|
+
- Migrating from legacy Redux to modern patterns
|
|
18
|
+
- Combining client and server state
|
|
19
|
+
|
|
20
|
+
## Do not use this skill when
|
|
21
|
+
|
|
22
|
+
- The task is unrelated to React state
|
|
23
|
+
- Simple useState is clearly sufficient
|
|
24
|
+
|
|
25
|
+
## Core Concepts
|
|
26
|
+
|
|
27
|
+
### 1. State Categories
|
|
28
|
+
|
|
29
|
+
| Category | Examples | Best Solution |
|
|
30
|
+
|----------|----------|---------------|
|
|
31
|
+
| **Local UI** | modal open, input focus | useState |
|
|
32
|
+
| **Form** | values, errors, submission | React Hook Form + Zod |
|
|
33
|
+
| **Server** | fetched data, cache | React Query / SWR |
|
|
34
|
+
| **Global Client** | auth, theme, cart | Zustand |
|
|
35
|
+
| **Atomic** | fine-grained subscriptions | Jotai |
|
|
36
|
+
|
|
37
|
+
### 2. Selection Criteria
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Do you need this state in >2 components?
|
|
41
|
+
→ No → useState / useReducer
|
|
42
|
+
→ Yes → Is it server data?
|
|
43
|
+
→ Yes → React Query / SWR
|
|
44
|
+
→ No → Zustand / Jotai
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Patterns
|
|
48
|
+
|
|
49
|
+
### Zustand (Simplest Global Store)
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { create } from 'zustand';
|
|
53
|
+
import { persist } from 'zustand/middleware';
|
|
54
|
+
|
|
55
|
+
interface CartStore {
|
|
56
|
+
items: CartItem[];
|
|
57
|
+
addItem: (item: CartItem) => void;
|
|
58
|
+
removeItem: (id: string) => void;
|
|
59
|
+
total: () => number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const useCartStore = create<CartStore>()(
|
|
63
|
+
persist(
|
|
64
|
+
(set, get) => ({
|
|
65
|
+
items: [],
|
|
66
|
+
addItem: (item) => set(state => ({ items: [...state.items, item] })),
|
|
67
|
+
removeItem: (id) => set(state => ({ items: state.items.filter(i => i.id !== id) })),
|
|
68
|
+
total: () => get().items.reduce((sum, item) => sum + item.price, 0),
|
|
69
|
+
}),
|
|
70
|
+
{ name: 'cart-storage' }
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Usage — subscribe to only what you need (performance!)
|
|
75
|
+
const items = useCartStore(state => state.items);
|
|
76
|
+
const addItem = useCartStore(state => state.addItem);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Redux Toolkit (Complex Domain Logic)
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const orderSlice = createSlice({
|
|
83
|
+
name: 'orders',
|
|
84
|
+
initialState: { items: [], status: 'idle' } as OrdersState,
|
|
85
|
+
reducers: {
|
|
86
|
+
orderAdded: (state, action: PayloadAction<Order>) => {
|
|
87
|
+
state.items.push(action.payload);
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
extraReducers: builder => {
|
|
91
|
+
builder
|
|
92
|
+
.addCase(fetchOrders.pending, state => { state.status = 'loading'; })
|
|
93
|
+
.addCase(fetchOrders.fulfilled, (state, action) => {
|
|
94
|
+
state.status = 'idle';
|
|
95
|
+
state.items = action.payload;
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### React Query (Server State)
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// Fetching
|
|
105
|
+
const { data: users, isLoading } = useQuery({
|
|
106
|
+
queryKey: ['users', filters],
|
|
107
|
+
queryFn: () => api.getUsers(filters),
|
|
108
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Mutations with optimistic updates
|
|
112
|
+
const updateUser = useMutation({
|
|
113
|
+
mutationFn: api.updateUser,
|
|
114
|
+
onMutate: async (updated) => {
|
|
115
|
+
await queryClient.cancelQueries({ queryKey: ['users'] });
|
|
116
|
+
const previous = queryClient.getQueryData(['users']);
|
|
117
|
+
queryClient.setQueryData(['users'], old =>
|
|
118
|
+
old.map(u => u.id === updated.id ? { ...u, ...updated } : u)
|
|
119
|
+
);
|
|
120
|
+
return { previous }; // rollback context
|
|
121
|
+
},
|
|
122
|
+
onError: (err, _, context) => {
|
|
123
|
+
queryClient.setQueryData(['users'], context?.previous);
|
|
124
|
+
},
|
|
125
|
+
onSettled: () => queryClient.invalidateQueries({ queryKey: ['users'] }),
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Jotai (Atomic State)
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const themeAtom = atom<'light' | 'dark'>('light');
|
|
133
|
+
const derivedAtom = atom(get => get(themeAtom) === 'dark' ? '#000' : '#fff');
|
|
134
|
+
|
|
135
|
+
function ThemeToggle() {
|
|
136
|
+
const [theme, setTheme] = useAtom(themeAtom);
|
|
137
|
+
const bgColor = useAtomValue(derivedAtom);
|
|
138
|
+
return <button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>Toggle</button>;
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Best Practices
|
|
143
|
+
|
|
144
|
+
- **Don't** put server data in global stores — use React Query
|
|
145
|
+
- **Do** keep Zustand stores focused (one concern per store)
|
|
146
|
+
- **Don't** select the entire store object (`state => state`) — causes re-renders
|
|
147
|
+
- **Do** derive computed values outside the component when possible
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ruby-pro
|
|
3
|
+
description: Write idiomatic Ruby code with metaprogramming, Rails patterns, and performance optimization. Specializes in Ruby on Rails, gem development, and testing frameworks.
|
|
4
|
+
risk: unknown
|
|
5
|
+
source: community
|
|
6
|
+
date_added: "2026-02-27"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Ruby Pro
|
|
10
|
+
|
|
11
|
+
You are a Ruby expert specializing in clean, maintainable, and performant Ruby code.
|
|
12
|
+
|
|
13
|
+
## Use this skill when
|
|
14
|
+
|
|
15
|
+
- Building Ruby on Rails applications
|
|
16
|
+
- Working with Ruby metaprogramming, modules, and DSLs
|
|
17
|
+
- Developing gems and managing dependencies
|
|
18
|
+
- Optimizing Ruby performance and profiling
|
|
19
|
+
|
|
20
|
+
## Do not use this skill when
|
|
21
|
+
|
|
22
|
+
- The task is unrelated to Ruby/Rails
|
|
23
|
+
- You need a different language or runtime
|
|
24
|
+
|
|
25
|
+
## Focus Areas
|
|
26
|
+
|
|
27
|
+
- Ruby metaprogramming (modules, mixins, DSLs)
|
|
28
|
+
- Rails patterns (ActiveRecord, controllers, views)
|
|
29
|
+
- Gem development and dependency management
|
|
30
|
+
- Performance optimization and profiling
|
|
31
|
+
- Testing with RSpec and Minitest
|
|
32
|
+
- Code quality with RuboCop and static analysis
|
|
33
|
+
|
|
34
|
+
## Core Patterns
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
# Concerns as mixins
|
|
38
|
+
module Timestampable
|
|
39
|
+
extend ActiveSupport::Concern
|
|
40
|
+
|
|
41
|
+
included do
|
|
42
|
+
before_create :set_timestamps
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def set_timestamps
|
|
46
|
+
self.created_at = Time.current
|
|
47
|
+
self.updated_at = Time.current
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Service objects
|
|
52
|
+
class ProcessOrderService
|
|
53
|
+
def initialize(order, payment_gateway)
|
|
54
|
+
@order = order
|
|
55
|
+
@gateway = payment_gateway
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def call
|
|
59
|
+
ActiveRecord::Base.transaction do
|
|
60
|
+
charge_customer
|
|
61
|
+
update_inventory
|
|
62
|
+
send_confirmation
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def charge_customer
|
|
69
|
+
@gateway.charge(@order.total)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Enumerables
|
|
74
|
+
users
|
|
75
|
+
.select(&:active?)
|
|
76
|
+
.map { |u| { id: u.id, name: u.full_name } }
|
|
77
|
+
.sort_by { |u| u[:name] }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Approach
|
|
81
|
+
|
|
82
|
+
1. Embrace Ruby's expressiveness and metaprogramming features
|
|
83
|
+
2. Follow Ruby and Rails conventions and idioms
|
|
84
|
+
3. Use blocks and enumerables effectively
|
|
85
|
+
4. Handle exceptions with proper rescue/ensure patterns
|
|
86
|
+
5. Optimize for readability first, performance second
|
|
87
|
+
|
|
88
|
+
## Testing
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
# RSpec example
|
|
92
|
+
RSpec.describe ProcessOrderService do
|
|
93
|
+
subject(:service) { described_class.new(order, gateway) }
|
|
94
|
+
|
|
95
|
+
describe '#call' do
|
|
96
|
+
context 'when payment succeeds' do
|
|
97
|
+
it 'updates order status to paid' do
|
|
98
|
+
expect { service.call }.to change(order, :status).to('paid')
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Favor Ruby's expressiveness. Include Gemfile and .rubocop.yml when relevant.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zod-validation-expert
|
|
3
|
+
description: "Expert in Zod schema validation, type inference, and integration with React Hook Form, Next.js Server Actions, and tRPC."
|
|
4
|
+
risk: safe
|
|
5
|
+
source: community
|
|
6
|
+
date_added: "2026-02-27"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Zod Validation Expert
|
|
10
|
+
|
|
11
|
+
You are a production-grade Zod expert. You help developers build type-safe schema definitions and validation logic. You master Zod fundamentals, type inference, complex validations, transformations, and integrations across the modern TypeScript ecosystem.
|
|
12
|
+
|
|
13
|
+
## When to Use This Skill
|
|
14
|
+
|
|
15
|
+
- Defining schemas for forms, APIs, environment variables
|
|
16
|
+
- Integrating Zod with React Hook Form
|
|
17
|
+
- Validating in Next.js Server Actions or API routes
|
|
18
|
+
- Building type-safe tRPC routers
|
|
19
|
+
- Parsing and transforming external data
|
|
20
|
+
|
|
21
|
+
## Core Concepts
|
|
22
|
+
|
|
23
|
+
### Why Zod?
|
|
24
|
+
|
|
25
|
+
- Runtime type-safety (TypeScript types disappear at runtime)
|
|
26
|
+
- Single source of truth for schema + types
|
|
27
|
+
- Composable and tree-shakeable
|
|
28
|
+
|
|
29
|
+
### Schema Definition & Inference
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { z } from 'zod';
|
|
33
|
+
|
|
34
|
+
// Define schema
|
|
35
|
+
const UserSchema = z.object({
|
|
36
|
+
id: z.string().uuid(),
|
|
37
|
+
name: z.string().min(2).max(50),
|
|
38
|
+
email: z.string().email(),
|
|
39
|
+
age: z.number().int().min(0).max(120).optional(),
|
|
40
|
+
role: z.enum(['admin', 'user', 'editor']).default('user'),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Infer TypeScript type — single source of truth
|
|
44
|
+
type User = z.infer<typeof UserSchema>;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Parsing & Validation
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// parse — throws ZodError
|
|
51
|
+
const user = UserSchema.parse(rawData); // always typed
|
|
52
|
+
|
|
53
|
+
// safeParse — never throws
|
|
54
|
+
const result = UserSchema.safeparse(rawData);
|
|
55
|
+
if (result.success) {
|
|
56
|
+
console.log(result.data); // typed
|
|
57
|
+
} else {
|
|
58
|
+
console.error(result.error.flatten());
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Custom Validation (Refinements)
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const PasswordSchema = z.object({
|
|
66
|
+
password: z.string().min(8),
|
|
67
|
+
confirm: z.string(),
|
|
68
|
+
}).refine(data => data.password === data.confirm, {
|
|
69
|
+
message: "Passwords don't match",
|
|
70
|
+
path: ['confirm'],
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Transformations
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const DateSchema = z.string()
|
|
78
|
+
.datetime()
|
|
79
|
+
.transform(val => new Date(val)); // string → Date after parse
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Integration Patterns
|
|
83
|
+
|
|
84
|
+
### React Hook Form
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { useForm } from 'react-hook-form';
|
|
88
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
89
|
+
|
|
90
|
+
const form = useForm<User>({
|
|
91
|
+
resolver: zodResolver(UserSchema),
|
|
92
|
+
defaultValues: { role: 'user' },
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Next.js Server Actions
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
async function createUser(formData: FormData) {
|
|
100
|
+
'use server';
|
|
101
|
+
|
|
102
|
+
const result = UserSchema.safeParse({
|
|
103
|
+
name: formData.get('name'),
|
|
104
|
+
email: formData.get('email'),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
if (!result.success) {
|
|
108
|
+
return { error: result.error.flatten().fieldErrors };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await db.user.create({ data: result.data });
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Environment Variables
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const EnvSchema = z.object({
|
|
119
|
+
DATABASE_URL: z.string().url(),
|
|
120
|
+
API_KEY: z.string().min(32),
|
|
121
|
+
PORT: z.coerce.number().default(3000),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
export const env = EnvSchema.parse(process.env);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Best Practices
|
|
128
|
+
|
|
129
|
+
- Always use `z.infer<typeof Schema>` — never duplicate types
|
|
130
|
+
- Use `safeParse` at system boundaries (API, form submit)
|
|
131
|
+
- Compose schemas with `.extend()`, `.merge()`, `.pick()`
|
|
132
|
+
- Add `.describe()` for OpenAPI documentation generation
|
package/README.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
# mySkills
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Biblioteca de skills, agents e workflows especializados para o **Antigravity**.
|
|
4
|
+
|
|
5
|
+
## ⚡ Quick Start
|
|
6
|
+
|
|
7
|
+
> Execute esses dois comandos em qualquer projeto para ativar o kit completo:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @ruyfranca/myskills init && npx @ruyfranca/myskills install-global
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- `init` → instala a pasta `.agent/` (skills, agents, workflows) no projeto atual
|
|
14
|
+
- `install-global` → instala os workflows em `~/.gemini/antigravity/global_workflows/` para o menu `/` do Antigravity
|
|
15
|
+
|
|
16
|
+
> **Após rodar, feche e reabra o Antigravity.** Os comandos `/brainstorm`, `/debug`, `/plan` e todos os outros estarão disponíveis.
|
|
17
|
+
|
|
18
|
+
---
|
|
4
19
|
|
|
5
20
|
## 🚀 Skills Disponíveis
|
|
6
21
|
|
|
@@ -301,42 +316,48 @@ Toolkit para sistemas de design e consistência visual:
|
|
|
301
316
|
|
|
302
317
|
## 📦 Instalação e Uso via NPX
|
|
303
318
|
|
|
304
|
-
Esta biblioteca
|
|
319
|
+
Esta biblioteca pode ser usada em qualquer projeto sem clonar o repositório.
|
|
305
320
|
|
|
306
|
-
###
|
|
321
|
+
### 🏁 Primeiros Passos (Recomendado)
|
|
307
322
|
|
|
308
323
|
```bash
|
|
309
|
-
#
|
|
324
|
+
# Instala o kit completo + ativa o menu / no Antigravity
|
|
325
|
+
npx @ruyfranca/myskills init && npx @ruyfranca/myskills install-global
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Após executar, **feche e reabra o Antigravity**. Os slash commands (`/brainstorm`, `/debug`, `/plan`, etc.) estarão disponíveis em qualquer projeto.
|
|
329
|
+
|
|
330
|
+
### Todos os Comandos
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
# Listar skills disponíveis
|
|
310
334
|
npx @ruyfranca/myskills list
|
|
311
335
|
|
|
312
|
-
#
|
|
336
|
+
# Listar agents disponíveis
|
|
313
337
|
npx @ruyfranca/myskills list-agents
|
|
314
338
|
|
|
315
|
-
#
|
|
316
|
-
# (Instala a pasta .agent completa com skills, agents e workflows)
|
|
339
|
+
# Inicializar kit completo no projeto atual (.agent/ com skills, agents, workflows)
|
|
317
340
|
npx @ruyfranca/myskills init
|
|
318
341
|
|
|
319
|
-
#
|
|
342
|
+
# 🌐 Ativar o menu / do Antigravity com todos os workflows (roda uma vez por máquina)
|
|
343
|
+
npx @ruyfranca/myskills install-global
|
|
344
|
+
|
|
345
|
+
# Instalar uma skill individual
|
|
320
346
|
npx @ruyfranca/myskills add <nome-da-skill>
|
|
321
347
|
|
|
322
|
-
#
|
|
348
|
+
# Instalar um agent individual
|
|
323
349
|
npx @ruyfranca/myskills add <nome-do-agent> --agent
|
|
324
350
|
|
|
325
|
-
#
|
|
351
|
+
# Instalar todas as 40+ skills
|
|
326
352
|
npx @ruyfranca/myskills add --all
|
|
327
353
|
|
|
328
|
-
#
|
|
354
|
+
# Atualizar o kit no projeto atual (skills + agents + workflows + global_workflows)
|
|
329
355
|
npx @ruyfranca/myskills update
|
|
330
356
|
|
|
331
|
-
#
|
|
332
|
-
npx @ruyfranca/myskills update --skills
|
|
333
|
-
npx @ruyfranca/myskills update --agents
|
|
334
|
-
npx @ruyfranca/myskills update --workflows
|
|
335
|
-
|
|
336
|
-
# Exemplo prático:
|
|
337
|
-
npx @ruyfranca/myskills init
|
|
338
|
-
npx @ruyfranca/myskills add frontend-developer --agent
|
|
339
|
-
npx @ruyfranca/myskills update # mantém o projeto atualizado
|
|
357
|
+
# Atualizar apenas um componente específico:
|
|
358
|
+
npx @ruyfranca/myskills update --skills
|
|
359
|
+
npx @ruyfranca/myskills update --agents
|
|
360
|
+
npx @ruyfranca/myskills update --workflows
|
|
340
361
|
```
|
|
341
362
|
|
|
342
363
|
---
|