@mind-fold/open-flow 0.2.10 → 0.2.12

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.
Files changed (40) hide show
  1. package/dist/templates/commands/break-loop.txt +1 -1
  2. package/dist/templates/commands/check-cross-layer.txt +3 -3
  3. package/dist/templates/commands/create-command.txt +5 -5
  4. package/dist/templates/commands/extract-llm-docs.txt +18 -18
  5. package/dist/templates/commands/extract-to-rules.txt +38 -38
  6. package/dist/templates/commands/finish-work.txt +5 -5
  7. package/dist/templates/commands/generate-backend-structure.txt +27 -27
  8. package/dist/templates/commands/generate-frontend-structure.txt +15 -15
  9. package/dist/templates/commands/integrate-skill.txt +30 -30
  10. package/dist/templates/commands/onboard-developer.txt +487 -39
  11. package/dist/templates/commands/record-agent-flow.txt +4 -4
  12. package/dist/templates/commands/sync-from-runtime.txt +2 -2
  13. package/dist/templates/markdown/agent-progress-index.md.txt +9 -9
  14. package/dist/templates/markdown/backend-doc.md.txt +12 -12
  15. package/dist/templates/markdown/flow.md.txt +99 -99
  16. package/dist/templates/markdown/frontend-doc.md.txt +11 -11
  17. package/dist/templates/markdown/structure/backend/database-guidelines.md.txt +6 -6
  18. package/dist/templates/markdown/structure/backend/directory-structure.md.txt +28 -28
  19. package/dist/templates/markdown/structure/backend/index.md.txt +10 -10
  20. package/dist/templates/markdown/structure/backend/logging-guidelines.md.txt +4 -4
  21. package/dist/templates/markdown/structure/backend/quality-guidelines.md.txt +12 -12
  22. package/dist/templates/markdown/structure/backend/type-safety.md.txt +6 -6
  23. package/dist/templates/markdown/structure/flows/code-reuse-thinking-guide.md.txt +17 -17
  24. package/dist/templates/markdown/structure/flows/cross-layer-thinking-guide.md.txt +96 -96
  25. package/dist/templates/markdown/structure/flows/index.md.txt +31 -31
  26. package/dist/templates/markdown/structure/flows/pre-implementation-checklist.md.txt +19 -19
  27. package/dist/templates/markdown/structure/flows/spec-flow-template.md.txt +20 -20
  28. package/dist/templates/markdown/structure/frontend/component-guidelines.md.txt +12 -12
  29. package/dist/templates/markdown/structure/frontend/directory-structure.md.txt +61 -61
  30. package/dist/templates/markdown/structure/frontend/hook-guidelines.md.txt +5 -5
  31. package/dist/templates/markdown/structure/frontend/index.md.txt +13 -13
  32. package/dist/templates/markdown/structure/frontend/quality-guidelines.md.txt +21 -21
  33. package/dist/templates/markdown/structure/frontend/state-management.md.txt +12 -12
  34. package/dist/templates/markdown/structure/frontend/type-safety.md.txt +11 -11
  35. package/dist/templates/scripts/add-session.sh.txt +5 -5
  36. package/dist/templates/scripts/extract-md-headings.sh.txt +3 -3
  37. package/dist/templates/scripts/get-context.sh.txt +1 -1
  38. package/dist/templates/scripts/init-developer.sh.txt +1 -1
  39. package/dist/templates/scripts/update-index.sh.txt +2 -2
  40. package/package.json +1 -1
@@ -16,23 +16,23 @@
16
16
 
17
17
  ```
18
18
  [Source]
19
-
20
-
21
- [Layer 1] ─────────────────────────────┐
22
-
23
- Data: { field1, field2 }
24
- Transform: none
25
-
26
-
27
- [Layer 2] ─────────────────────────────┤
28
-
29
- Data: { field1, field2, extra }
30
- Transform: add computed field
31
-
32
-
33
- [Layer 3] ─────────────────────────────┘
34
-
35
-
19
+ |
20
+ v
21
+ [Layer 1] -----------------------------+
22
+ | |
23
+ | Data: { field1, field2 } |
24
+ | Transform: none |
25
+ | |
26
+ v |
27
+ [Layer 2] -----------------------------|
28
+ | |
29
+ | Data: { field1, field2, extra } |
30
+ | Transform: add computed field |
31
+ | |
32
+ v |
33
+ [Layer 3] -----------------------------+
34
+ |
35
+ v
36
36
  [Consumer]
37
37
  ```
38
38
 
@@ -63,8 +63,8 @@
63
63
  **Transformation**: None (pass-through)
64
64
 
65
65
  **Error Handling**:
66
- - Validation errors 400 response
67
- - Not found 404 response
66
+ - Validation errors -> 400 response
67
+ - Not found -> 404 response
68
68
 
69
69
  ---
70
70
 
@@ -87,7 +87,7 @@
87
87
  - Adds `computed` field based on `field1` and `field2`
88
88
 
89
89
  **Error Handling**:
90
- - Business logic errors throw CustomError
90
+ - Business logic errors -> throw CustomError
91
91
 
92
92
  ---
93
93
 
@@ -68,10 +68,10 @@ Use proper HTML elements for their intended purpose.
68
68
  ### Interactive Elements
69
69
 
70
70
  ```typescript
71
- // GOOD: Use button for actions
71
+ // [OK] GOOD: Use button for actions
72
72
  <button onClick={handleClick}>Click me</button>
73
73
 
74
- // BAD: Don't use div as button
74
+ // [X] BAD: Don't use div as button
75
75
  <div role="button" onClick={handleClick}>Click me</div>
76
76
  ```
77
77
 
@@ -84,14 +84,14 @@ Use proper HTML elements for their intended purpose.
84
84
  // Link: navigates to a URL
85
85
  <Link href="/about">About</Link>
86
86
 
87
- // BAD: Button that looks like a link but navigates
87
+ // [X] BAD: Button that looks like a link but navigates
88
88
  <button onClick={() => router.push('/about')}>About</button>
89
89
  ```
90
90
 
91
91
  ### Headings
92
92
 
93
93
  ```typescript
94
- // GOOD: Proper heading hierarchy
94
+ // [OK] GOOD: Proper heading hierarchy
95
95
  <article>
96
96
  <h1>Page Title</h1>
97
97
  <section>
@@ -100,7 +100,7 @@ Use proper HTML elements for their intended purpose.
100
100
  </section>
101
101
  </article>
102
102
 
103
- // BAD: Skipping heading levels
103
+ // [X] BAD: Skipping heading levels
104
104
  <h1>Title</h1>
105
105
  <h3>Subsection</h3> // Missing h2
106
106
  ```
@@ -108,14 +108,14 @@ Use proper HTML elements for their intended purpose.
108
108
  ### Lists
109
109
 
110
110
  ```typescript
111
- // GOOD: Use list elements for lists
111
+ // [OK] GOOD: Use list elements for lists
112
112
  <ul>
113
113
  {items.map(item => (
114
114
  <li key={item.id}>{item.name}</li>
115
115
  ))}
116
116
  </ul>
117
117
 
118
- // BAD: Divs for list
118
+ // [X] BAD: Divs for list
119
119
  <div>
120
120
  {items.map(item => (
121
121
  <div key={item.id}>{item.name}</div>
@@ -132,7 +132,7 @@ Use proper HTML elements for their intended purpose.
132
132
  ```typescript
133
133
  import Image from 'next/image';
134
134
 
135
- // GOOD: Use Next.js Image
135
+ // [OK] GOOD: Use Next.js Image
136
136
  <Image
137
137
  src="/avatar.png"
138
138
  alt="User avatar"
@@ -140,7 +140,7 @@ import Image from 'next/image';
140
140
  height={100}
141
141
  />
142
142
 
143
- // BAD: Native img tag
143
+ // [X] BAD: Native img tag
144
144
  <img src="/avatar.png" alt="User avatar" />
145
145
  ```
146
146
 
@@ -172,17 +172,17 @@ module.exports = {
172
172
  ### Labels for Inputs
173
173
 
174
174
  ```typescript
175
- // GOOD: Associated label
175
+ // [OK] GOOD: Associated label
176
176
  <label htmlFor="email">Email</label>
177
177
  <input id="email" type="email" />
178
178
 
179
- // GOOD: Implicit label
179
+ // [OK] GOOD: Implicit label
180
180
  <label>
181
181
  Email
182
182
  <input type="email" />
183
183
  </label>
184
184
 
185
- // BAD: No label
185
+ // [X] BAD: No label
186
186
  <input type="email" placeholder="Email" />
187
187
  ```
188
188
 
@@ -8,37 +8,37 @@
8
8
 
9
9
  ```
10
10
  src/
11
- ├── app/ # Next.js App Router (if using Next.js)
12
- ├── (marketing)/ # Marketing pages group
13
- ├── (app)/ # Application pages group
14
- └── api/ # API routes
15
-
16
- ├── components/ # Shared components
17
- ├── ui/ # Base UI components (Button, Input, etc.)
18
- └── common/ # Composite components (Header, Footer, etc.)
19
-
20
- ├── modules/ # Feature modules
21
- └── {feature}/
22
- ├── components/ # Feature-specific components
23
- ├── hooks/ # Feature-specific hooks
24
- ├── context/ # Feature-specific context
25
- ├── lib/ # Feature-specific utilities
26
- └── types.ts # Feature types
27
-
28
- ├── hooks/ # Shared hooks
29
- ├── use-debounce.ts
30
- └── use-local-storage.ts
31
-
32
- ├── lib/ # Shared utilities
33
- ├── api-client.ts # API client setup
34
- ├── utils.ts # Helper functions
35
- └── constants.ts # Global constants
36
-
37
- ├── types/ # Shared type definitions
38
- └── index.ts
39
-
40
- └── styles/ # Global styles
41
- └── globals.css
11
+ |-- app/ # Next.js App Router (if using Next.js)
12
+ | |-- (marketing)/ # Marketing pages group
13
+ | |-- (app)/ # Application pages group
14
+ | \-- api/ # API routes
15
+ |
16
+ |-- components/ # Shared components
17
+ | |-- ui/ # Base UI components (Button, Input, etc.)
18
+ | \-- common/ # Composite components (Header, Footer, etc.)
19
+ |
20
+ |-- modules/ # Feature modules
21
+ | \-- {feature}/
22
+ | |-- components/ # Feature-specific components
23
+ | |-- hooks/ # Feature-specific hooks
24
+ | |-- context/ # Feature-specific context
25
+ | |-- lib/ # Feature-specific utilities
26
+ | \-- types.ts # Feature types
27
+ |
28
+ |-- hooks/ # Shared hooks
29
+ | |-- use-debounce.ts
30
+ | \-- use-local-storage.ts
31
+ |
32
+ |-- lib/ # Shared utilities
33
+ | |-- api-client.ts # API client setup
34
+ | |-- utils.ts # Helper functions
35
+ | \-- constants.ts # Global constants
36
+ |
37
+ |-- types/ # Shared type definitions
38
+ | \-- index.ts
39
+ |
40
+ \-- styles/ # Global styles
41
+ \-- globals.css
42
42
  ```
43
43
 
44
44
  ---
@@ -49,23 +49,23 @@ Each feature module is self-contained:
49
49
 
50
50
  ```
51
51
  modules/users/
52
- ├── components/
53
- ├── user-card.tsx # Display component
54
- ├── user-form.tsx # Form component
55
- └── user-list.tsx # List component
56
-
57
- ├── hooks/
58
- ├── use-user.ts # Single user query
59
- ├── use-users.ts # Users list query
60
- └── use-update-user.ts # Update mutation
61
-
62
- ├── context/
63
- └── user-context.tsx # Feature-level state
64
-
65
- ├── lib/
66
- └── user-utils.ts # Feature-specific helpers
67
-
68
- └── types.ts # Feature types (if not from API)
52
+ |-- components/
53
+ | |-- user-card.tsx # Display component
54
+ | |-- user-form.tsx # Form component
55
+ | \-- user-list.tsx # List component
56
+ |
57
+ |-- hooks/
58
+ | |-- use-user.ts # Single user query
59
+ | |-- use-users.ts # Users list query
60
+ | \-- use-update-user.ts # Update mutation
61
+ |
62
+ |-- context/
63
+ | \-- user-context.tsx # Feature-level state
64
+ |
65
+ |-- lib/
66
+ | \-- user-utils.ts # Feature-specific helpers
67
+ |
68
+ \-- types.ts # Feature types (if not from API)
69
69
  ```
70
70
 
71
71
  ---
@@ -76,23 +76,23 @@ modules/users/
76
76
 
77
77
  ```
78
78
  components/ui/
79
- ├── button.tsx # Base button
80
- ├── input.tsx # Base input
81
- ├── select.tsx # Base select
82
- ├── dialog.tsx # Modal dialog
83
- ├── dropdown-menu.tsx # Dropdown menu
84
- └── index.ts # Barrel export
79
+ |-- button.tsx # Base button
80
+ |-- input.tsx # Base input
81
+ |-- select.tsx # Base select
82
+ |-- dialog.tsx # Modal dialog
83
+ |-- dropdown-menu.tsx # Dropdown menu
84
+ \-- index.ts # Barrel export
85
85
  ```
86
86
 
87
87
  ### Common Components (Composites)
88
88
 
89
89
  ```
90
90
  components/common/
91
- ├── header.tsx # App header
92
- ├── sidebar.tsx # Navigation sidebar
93
- ├── page-layout.tsx # Page wrapper
94
- ├── error-boundary.tsx # Error boundary
95
- └── loading-spinner.tsx # Loading state
91
+ |-- header.tsx # App header
92
+ |-- sidebar.tsx # Navigation sidebar
93
+ |-- page-layout.tsx # Page wrapper
94
+ |-- error-boundary.tsx # Error boundary
95
+ \-- loading-spinner.tsx # Loading state
96
96
  ```
97
97
 
98
98
  ---
@@ -157,12 +157,12 @@ import styles from './user-list.module.css';
157
157
  ## Module Boundaries
158
158
 
159
159
  ```
160
- ALLOWED:
160
+ [OK] ALLOWED:
161
161
  - modules/users/ imports from components/ui/
162
162
  - modules/users/ imports from hooks/
163
163
  - modules/users/ imports from lib/
164
164
 
165
- NOT ALLOWED:
165
+ [X] NOT ALLOWED:
166
166
  - modules/users/ imports from modules/orders/
167
167
  (Use shared hooks or lift to common location)
168
168
  ```
@@ -50,12 +50,12 @@ export function useUsers(page: number, pageSize: number = 20) {
50
50
  ### Query Key Rules
51
51
 
52
52
  ```typescript
53
- // GOOD: Include all dependencies in query key
53
+ // [OK] GOOD: Include all dependencies in query key
54
54
  queryKey: ['user', userId]
55
55
  queryKey: ['users', { page, pageSize, filter }]
56
56
  queryKey: ['posts', userId, 'comments']
57
57
 
58
- // BAD: Missing dependencies
58
+ // [X] BAD: Missing dependencies
59
59
  queryKey: ['user'] // Same key for different users!
60
60
  queryKey: ['users'] // Same key for different pages!
61
61
  ```
@@ -258,15 +258,15 @@ const toggle = useCallback(() => setValue(v => !v), []);
258
258
  ```typescript
259
259
  // Don't fetch in useEffect
260
260
  useEffect(() => {
261
- fetch('/api/user').then(...) // Use useQuery instead
261
+ fetch('/api/user').then(...) // [X] Use useQuery instead
262
262
  }, []);
263
263
 
264
264
  // Don't ignore error states
265
265
  const { data } = useUser(id);
266
- return <div>{data.name}</div>; // data might be undefined
266
+ return <div>{data.name}</div>; // [X] data might be undefined
267
267
 
268
268
  // Don't mutate query data directly
269
- data.name = 'New Name'; // Use mutation
269
+ data.name = 'New Name'; // [X] Use mutation
270
270
  ```
271
271
 
272
272
  ---
@@ -36,19 +36,19 @@ This collection of guidelines covers essential patterns and best practices for b
36
36
 
37
37
  ```
38
38
  src/
39
- ├── components/ # Shared components
40
- ├── ui/ # Base UI components
41
- └── common/ # Common composite components
42
-
43
- ├── modules/ # Feature modules
44
- └── {feature}/
45
- ├── components/ # Feature-specific components
46
- ├── hooks/ # Feature-specific hooks
47
- └── types.ts # Feature types
48
-
49
- ├── hooks/ # Shared hooks
50
- ├── lib/ # Utilities
51
- └── types/ # Shared types
39
+ |-- components/ # Shared components
40
+ | |-- ui/ # Base UI components
41
+ | \-- common/ # Common composite components
42
+ |
43
+ |-- modules/ # Feature modules
44
+ | \-- {feature}/
45
+ | |-- components/ # Feature-specific components
46
+ | |-- hooks/ # Feature-specific hooks
47
+ | \-- types.ts # Feature types
48
+ |
49
+ |-- hooks/ # Shared hooks
50
+ |-- lib/ # Utilities
51
+ \-- types/ # Shared types
52
52
  ```
53
53
 
54
54
  ### Key Rules
@@ -26,11 +26,11 @@ pnpm test
26
26
  ### Any Type
27
27
 
28
28
  ```typescript
29
- // FORBIDDEN
29
+ // [X] FORBIDDEN
30
30
  function process(data: any) { ... }
31
31
  const result: any = await fetch(...);
32
32
 
33
- // REQUIRED
33
+ // [OK] REQUIRED
34
34
  function process(data: unknown) {
35
35
  if (isValidData(data)) {
36
36
  // Now data is typed
@@ -41,11 +41,11 @@ function process(data: unknown) {
41
41
  ### Non-Null Assertions
42
42
 
43
43
  ```typescript
44
- // FORBIDDEN
44
+ // [X] FORBIDDEN
45
45
  const name = user!.name;
46
46
  const element = document.querySelector('.item')!;
47
47
 
48
- // REQUIRED
48
+ // [OK] REQUIRED
49
49
  if (!user) return null;
50
50
  const name = user.name;
51
51
 
@@ -56,11 +56,11 @@ if (!element) return;
56
56
  ### Type Assertions Without Validation
57
57
 
58
58
  ```typescript
59
- // FORBIDDEN
59
+ // [X] FORBIDDEN
60
60
  const data = response as UserData;
61
61
  const config = JSON.parse(str) as Config;
62
62
 
63
- // REQUIRED
63
+ // [OK] REQUIRED
64
64
  const data = userDataSchema.parse(response);
65
65
  if (!isUserData(response)) throw new Error('Invalid data');
66
66
  ```
@@ -68,11 +68,11 @@ if (!isUserData(response)) throw new Error('Invalid data');
68
68
  ### Div Instead of Semantic HTML
69
69
 
70
70
  ```typescript
71
- // FORBIDDEN
71
+ // [X] FORBIDDEN
72
72
  <div role="button" onClick={handleClick}>Click</div>
73
73
  <div onClick={handleNavigate}>Go to page</div>
74
74
 
75
- // REQUIRED
75
+ // [OK] REQUIRED
76
76
  <button onClick={handleClick}>Click</button>
77
77
  <Link href="/page">Go to page</Link>
78
78
  ```
@@ -80,10 +80,10 @@ if (!isUserData(response)) throw new Error('Invalid data');
80
80
  ### Native img in Next.js
81
81
 
82
82
  ```typescript
83
- // FORBIDDEN
83
+ // [X] FORBIDDEN
84
84
  <img src="/photo.jpg" alt="Photo" />
85
85
 
86
- // REQUIRED
86
+ // [OK] REQUIRED
87
87
  import Image from 'next/image';
88
88
  <Image src="/photo.jpg" alt="Photo" width={200} height={200} />
89
89
  ```
@@ -91,14 +91,14 @@ import Image from 'next/image';
91
91
  ### useEffect for Data Fetching
92
92
 
93
93
  ```typescript
94
- // FORBIDDEN
94
+ // [X] FORBIDDEN
95
95
  useEffect(() => {
96
96
  fetch('/api/users')
97
97
  .then(res => res.json())
98
98
  .then(setUsers);
99
99
  }, []);
100
100
 
101
- // REQUIRED
101
+ // [OK] REQUIRED
102
102
  const { data: users } = useQuery({
103
103
  queryKey: ['users'],
104
104
  queryFn: () => api.users.list(),
@@ -112,7 +112,7 @@ const { data: users } = useQuery({
112
112
  ### Handle Loading States
113
113
 
114
114
  ```typescript
115
- // REQUIRED: Handle all states
115
+ // [OK] REQUIRED: Handle all states
116
116
  function UserList() {
117
117
  const { data, isLoading, error } = useUsers();
118
118
 
@@ -127,7 +127,7 @@ function UserList() {
127
127
  ### Accessible Forms
128
128
 
129
129
  ```typescript
130
- // REQUIRED: Labels for all inputs
130
+ // [OK] REQUIRED: Labels for all inputs
131
131
  <label htmlFor="email">Email</label>
132
132
  <input id="email" type="email" aria-describedby="email-error" />
133
133
  {error && <span id="email-error" role="alert">{error}</span>}
@@ -136,7 +136,7 @@ function UserList() {
136
136
  ### Error Boundaries
137
137
 
138
138
  ```typescript
139
- // REQUIRED: Wrap feature modules
139
+ // [OK] REQUIRED: Wrap feature modules
140
140
  <ErrorBoundary fallback={<ErrorFallback />}>
141
141
  <FeatureModule />
142
142
  </ErrorBoundary>
@@ -196,32 +196,32 @@ export function UserCard({ user }: Props) {
196
196
  ### Memoization
197
197
 
198
198
  ```typescript
199
- // Memoize expensive calculations
199
+ // [OK] Memoize expensive calculations
200
200
  const sortedItems = useMemo(
201
201
  () => items.sort((a, b) => a.name.localeCompare(b.name)),
202
202
  [items]
203
203
  );
204
204
 
205
- // Memoize callbacks passed to children
205
+ // [OK] Memoize callbacks passed to children
206
206
  const handleClick = useCallback(() => {
207
207
  doSomething(id);
208
208
  }, [id]);
209
209
 
210
- // Don't memoize everything - only when needed
210
+ // [X] Don't memoize everything - only when needed
211
211
  const name = useMemo(() => user.name, [user.name]); // Unnecessary
212
212
  ```
213
213
 
214
214
  ### Avoid Unnecessary Rerenders
215
215
 
216
216
  ```typescript
217
- // BAD: Creates new object every render
217
+ // [X] BAD: Creates new object every render
218
218
  <Component style={{ color: 'red' }} />
219
219
 
220
- // GOOD: Stable reference
220
+ // [OK] GOOD: Stable reference
221
221
  const style = { color: 'red' }; // Outside component
222
222
  <Component style={style} />
223
223
 
224
- // GOOD: Or use className
224
+ // [OK] GOOD: Or use className
225
225
  <Component className="text-red" />
226
226
  ```
227
227
 
@@ -220,12 +220,12 @@ function ProductList() {
220
220
 
221
221
  ```
222
222
  Is the state needed by multiple components?
223
- ├─ No Local state (useState)
224
- └─ Yes Is it from the server?
225
- ├─ Yes React Query
226
- └─ No Should it persist in URL?
227
- ├─ Yes URL state (searchParams)
228
- └─ No Context or Zustand
223
+ |- No -> Local state (useState)
224
+ \- Yes -> Is it from the server?
225
+ |- Yes -> React Query
226
+ \- No -> Should it persist in URL?
227
+ |- Yes -> URL state (searchParams)
228
+ \- No -> Context or Zustand
229
229
  ```
230
230
 
231
231
  ---
@@ -235,7 +235,7 @@ Is the state needed by multiple components?
235
235
  ### Don't Sync Server State to Local State
236
236
 
237
237
  ```typescript
238
- // BAD: Duplicating server state
238
+ // [X] BAD: Duplicating server state
239
239
  const { data: users } = useUsers();
240
240
  const [localUsers, setLocalUsers] = useState<User[]>([]);
241
241
 
@@ -243,7 +243,7 @@ useEffect(() => {
243
243
  if (users) setLocalUsers(users);
244
244
  }, [users]);
245
245
 
246
- // GOOD: Use server state directly
246
+ // [OK] GOOD: Use server state directly
247
247
  const { data: users } = useUsers();
248
248
  // Use users directly, mutate with mutations
249
249
  ```
@@ -251,17 +251,17 @@ const { data: users } = useUsers();
251
251
  ### Don't Overuse Global State
252
252
 
253
253
  ```typescript
254
- // BAD: Everything in global state
254
+ // [X] BAD: Everything in global state
255
255
  const { isModalOpen, setModalOpen } = useGlobalStore();
256
256
 
257
- // GOOD: Local state for local UI
257
+ // [OK] GOOD: Local state for local UI
258
258
  const [isModalOpen, setIsModalOpen] = useState(false);
259
259
  ```
260
260
 
261
261
  ### Don't Put Derived State in State
262
262
 
263
263
  ```typescript
264
- // BAD: Storing derived value
264
+ // [X] BAD: Storing derived value
265
265
  const [items, setItems] = useState([]);
266
266
  const [filteredItems, setFilteredItems] = useState([]);
267
267
 
@@ -269,7 +269,7 @@ useEffect(() => {
269
269
  setFilteredItems(items.filter(i => i.active));
270
270
  }, [items]);
271
271
 
272
- // GOOD: Compute derived value
272
+ // [OK] GOOD: Compute derived value
273
273
  const [items, setItems] = useState([]);
274
274
  const filteredItems = items.filter(i => i.active);
275
275
  // Or useMemo for expensive computations