codecruise 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.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/bin/codecruise.js +68 -0
  4. package/config/CLAUDE.md +107 -0
  5. package/config/agents/analyst.md +48 -0
  6. package/config/agents/architect-reviewer.md +161 -0
  7. package/config/agents/architect.md +119 -0
  8. package/config/agents/critic.md +63 -0
  9. package/config/agents/developer.md +96 -0
  10. package/config/agents/devops.md +81 -0
  11. package/config/agents/orchestrator.md +91 -0
  12. package/config/agents/planner.md +139 -0
  13. package/config/agents/retro.md +52 -0
  14. package/config/agents/reviewer.md +101 -0
  15. package/config/agents/security-reviewer.md +57 -0
  16. package/config/agents/stack/expo/AGENT.md +473 -0
  17. package/config/agents/stack/expo/rules/critical.md +427 -0
  18. package/config/agents/stack/expo/rules/native.md +455 -0
  19. package/config/agents/stack/expo/rules/navigation.md +445 -0
  20. package/config/agents/stack/expo/rules/performance.md +415 -0
  21. package/config/agents/stack/fastify/AGENT.md +397 -0
  22. package/config/agents/stack/fastify/rules/api-design.md +283 -0
  23. package/config/agents/stack/fastify/rules/critical.md +232 -0
  24. package/config/agents/stack/fastify/rules/queues.md +303 -0
  25. package/config/agents/stack/fastify/rules/security.md +384 -0
  26. package/config/agents/stack/index.yaml +48 -0
  27. package/config/agents/stack/nextjs/AGENT.md +421 -0
  28. package/config/agents/stack/nextjs/rules/components.md +413 -0
  29. package/config/agents/stack/nextjs/rules/critical.md +391 -0
  30. package/config/agents/stack/nextjs/rules/performance.md +403 -0
  31. package/config/agents/stack/nextjs/rules/styling.md +334 -0
  32. package/config/agents/stack/shared-ts/AGENT.md +384 -0
  33. package/config/agents/stack/shared-ts/rules/critical.md +315 -0
  34. package/config/agents/stack/shared-ts/rules/patterns.md +384 -0
  35. package/config/agents/stack/shared-ts/rules/zod.md +427 -0
  36. package/config/agents/tester.md +79 -0
  37. package/config/commands/architect-discuss.md +366 -0
  38. package/config/commands/architect-list.md +160 -0
  39. package/config/commands/architect-review.md +111 -0
  40. package/config/commands/architect.md +118 -0
  41. package/config/commands/compact.md +118 -0
  42. package/config/commands/companion.md +279 -0
  43. package/config/commands/dashboard.md +152 -0
  44. package/config/commands/doctor.md +227 -0
  45. package/config/commands/dogfood-report.md +101 -0
  46. package/config/commands/flags/run-autonomous.md +110 -0
  47. package/config/commands/flags/run-pause.md +80 -0
  48. package/config/commands/ingest.md +173 -0
  49. package/config/commands/init.md +128 -0
  50. package/config/commands/metrics.md +87 -0
  51. package/config/commands/parallel.md +320 -0
  52. package/config/commands/pause.md +55 -0
  53. package/config/commands/plan-review.md +130 -0
  54. package/config/commands/plan.md +216 -0
  55. package/config/commands/production-check.md +308 -0
  56. package/config/commands/refine.md +323 -0
  57. package/config/commands/resume.md +72 -0
  58. package/config/commands/retro.md +121 -0
  59. package/config/commands/retry.md +75 -0
  60. package/config/commands/role.md +310 -0
  61. package/config/commands/run.md +417 -0
  62. package/config/commands/scope.md +85 -0
  63. package/config/commands/setup-permissions.md +104 -0
  64. package/config/commands/skip.md +75 -0
  65. package/config/commands/spec-forge.md +213 -0
  66. package/config/commands/spec-help.md +194 -0
  67. package/config/commands/spec-patch.md +342 -0
  68. package/config/commands/spec-resolve.md +110 -0
  69. package/config/commands/spec-review.md +153 -0
  70. package/config/commands/status.md +114 -0
  71. package/config/commands/sync.md +131 -0
  72. package/config/commands/task.md +138 -0
  73. package/config/commands/verify.md +124 -0
  74. package/config/hooks/README.md +632 -0
  75. package/config/hooks/activity-log.sh +187 -0
  76. package/config/hooks/anti-rationalize.sh +52 -0
  77. package/config/hooks/capture-verification.sh +112 -0
  78. package/config/hooks/collect-metrics.sh +135 -0
  79. package/config/hooks/enforce-file-scope.sh +75 -0
  80. package/config/hooks/enforce-state-machine.sh +161 -0
  81. package/config/hooks/enforce-tdd.sh +180 -0
  82. package/config/hooks/format.sh +40 -0
  83. package/config/hooks/lib/activity-helpers.sh +162 -0
  84. package/config/hooks/lib/read-settings.sh +71 -0
  85. package/config/hooks/load-context-skills.sh +95 -0
  86. package/config/hooks/notify.sh +81 -0
  87. package/config/hooks/pre-commit.sample +35 -0
  88. package/config/hooks/protect-files.sh +63 -0
  89. package/config/hooks/track-agents.sh +41 -0
  90. package/config/hooks/track-commands.sh +37 -0
  91. package/config/hooks/track-enforcement.sh +44 -0
  92. package/config/hooks/track-ooda.sh +77 -0
  93. package/config/hooks/validate-commit-msg.sh +35 -0
  94. package/config/hooks/validate-plan.sh +213 -0
  95. package/config/hooks/verify-criteria.sh +46 -0
  96. package/config/hooks/verify-todo-completion.sh +140 -0
  97. package/config/rules/comments.md +25 -0
  98. package/config/rules/decision-rules.md +308 -0
  99. package/config/rules/hygiene.md +247 -0
  100. package/config/rules/pattern-detection.md +372 -0
  101. package/config/rules/profiles.md +193 -0
  102. package/config/rules/recovery.md +83 -0
  103. package/config/rules/scope-detection.md +213 -0
  104. package/config/rules/standards.md +127 -0
  105. package/config/rules/workflow.md +121 -0
  106. package/config/schemas.md +767 -0
  107. package/config/settings.json +195 -0
  108. package/config/skills/backend/SKILL.md +734 -0
  109. package/config/skills/database/SKILL.md +426 -0
  110. package/config/skills/frontend/SKILL.md +434 -0
  111. package/config/skills/git/SKILL.md +396 -0
  112. package/config/skills/index.yaml +36 -0
  113. package/config/skills/observability/SKILL.md +430 -0
  114. package/config/skills/package-dev/SKILL.md +498 -0
  115. package/config/skills/performance/SKILL.md +378 -0
  116. package/config/skills/resilience/SKILL.md +573 -0
  117. package/config/skills/testing/SKILL.md +398 -0
  118. package/config/skills/testing-patterns/SKILL.md +276 -0
  119. package/config/skills/typescript/SKILL.md +152 -0
  120. package/config/templates/CLAUDE.md +70 -0
  121. package/config/templates/README.md +117 -0
  122. package/config/templates/steering/adr-template.md +102 -0
  123. package/config/templates/steering/product.md +60 -0
  124. package/config/templates/steering/rfc-template.md +159 -0
  125. package/config/templates/steering/structure.md +146 -0
  126. package/config/templates/steering/tech.md +85 -0
  127. package/package.json +40 -0
  128. package/src/install.js +163 -0
  129. package/src/report.js +310 -0
@@ -0,0 +1,415 @@
1
+ # Performance Rules - React Native
2
+
3
+ Optimization patterns for smooth 60fps apps.
4
+
5
+ ---
6
+
7
+ ## Lists
8
+
9
+ ### PERF-001: Use FlashList for long lists
10
+
11
+ ```typescript
12
+ import { FlashList } from '@shopify/flash-list';
13
+
14
+ // GOOD - FlashList for 50+ items
15
+ <FlashList
16
+ data={items}
17
+ keyExtractor={(item) => item.id}
18
+ renderItem={({ item }) => <ItemCard item={item} />}
19
+ estimatedItemSize={80} // Required! Measure your items
20
+ contentContainerStyle={{ padding: 16 }}
21
+ />
22
+
23
+ // FlatList OK for short lists
24
+ <FlatList
25
+ data={shortList} // < 50 items
26
+ renderItem={renderItem}
27
+ />
28
+ ```
29
+
30
+ ### PERF-002: Optimize list items
31
+
32
+ ```typescript
33
+ import { memo } from 'react';
34
+
35
+ // Memoize list items
36
+ const ItemCard = memo(function ItemCard({ item, onPress }: Props) {
37
+ return (
38
+ <Pressable onPress={() => onPress(item.id)}>
39
+ <Text>{item.title}</Text>
40
+ </Pressable>
41
+ );
42
+ });
43
+
44
+ // Stable callbacks
45
+ function ItemList() {
46
+ const handlePress = useCallback((id: string) => {
47
+ router.push(`/items/${id}`);
48
+ }, []);
49
+
50
+ const renderItem = useCallback(
51
+ ({ item }) => <ItemCard item={item} onPress={handlePress} />,
52
+ [handlePress]
53
+ );
54
+
55
+ return (
56
+ <FlashList
57
+ data={items}
58
+ renderItem={renderItem}
59
+ estimatedItemSize={80}
60
+ />
61
+ );
62
+ }
63
+ ```
64
+
65
+ ### PERF-003: List configuration
66
+
67
+ ```typescript
68
+ <FlashList
69
+ data={items}
70
+ renderItem={renderItem}
71
+ estimatedItemSize={80}
72
+
73
+ // Performance tweaks
74
+ removeClippedSubviews={true} // Unmount off-screen items
75
+ maxToRenderPerBatch={10} // Batch size
76
+ windowSize={5} // Render window (screens)
77
+ initialNumToRender={10} // Initial render count
78
+
79
+ // Smooth scrolling
80
+ maintainVisibleContentPosition={{
81
+ minIndexForVisible: 0,
82
+ }}
83
+ />
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Images
89
+
90
+ ### PERF-004: Optimize images
91
+
92
+ ```typescript
93
+ import { Image } from 'expo-image';
94
+
95
+ // Use expo-image (better caching)
96
+ <Image
97
+ source={{ uri: imageUrl }}
98
+ style={{ width: 200, height: 200 }}
99
+ contentFit="cover"
100
+ placeholder={blurhash}
101
+ transition={200}
102
+ cachePolicy="memory-disk"
103
+ />
104
+
105
+ // Resize on upload
106
+ import * as ImageManipulator from 'expo-image-manipulator';
107
+
108
+ async function resizeImage(uri: string) {
109
+ const result = await ImageManipulator.manipulateAsync(
110
+ uri,
111
+ [{ resize: { width: 800 } }],
112
+ { compress: 0.8, format: ImageManipulator.SaveFormat.JPEG }
113
+ );
114
+ return result.uri;
115
+ }
116
+ ```
117
+
118
+ ### PERF-005: Progressive loading
119
+
120
+ ```typescript
121
+ import { Image } from 'expo-image';
122
+
123
+ // With blurhash placeholder
124
+ <Image
125
+ source={{ uri: fullImageUrl }}
126
+ placeholder={item.blurhash}
127
+ contentFit="cover"
128
+ transition={300}
129
+ style={{ width: '100%', aspectRatio: 16/9 }}
130
+ />
131
+
132
+ // Generate blurhash on backend, store with image
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Rendering
138
+
139
+ ### PERF-006: Avoid re-renders
140
+
141
+ ```typescript
142
+ // BAD - Inline objects/functions
143
+ <View style={{ padding: 16 }}> {/* New object every render */}
144
+ <Pressable onPress={() => doSomething()}> {/* New function */}
145
+
146
+ // GOOD - Stable references
147
+ const styles = StyleSheet.create({ container: { padding: 16 } });
148
+ // Or with NativeWind
149
+ <View className="p-4">
150
+
151
+ const handlePress = useCallback(() => doSomething(), []);
152
+ <Pressable onPress={handlePress}>
153
+ ```
154
+
155
+ ### PERF-007: Memoize computed values
156
+
157
+ ```typescript
158
+ // BAD - Computed every render
159
+ function UserList({ users, filter }) {
160
+ const filtered = users.filter(u => u.role === filter); // Every render!
161
+ return <FlashList data={filtered} ... />;
162
+ }
163
+
164
+ // GOOD - Memoized
165
+ function UserList({ users, filter }) {
166
+ const filtered = useMemo(
167
+ () => users.filter(u => u.role === filter),
168
+ [users, filter]
169
+ );
170
+ return <FlashList data={filtered} ... />;
171
+ }
172
+ ```
173
+
174
+ ### PERF-008: Defer expensive operations
175
+
176
+ ```typescript
177
+ import { InteractionManager } from 'react-native';
178
+
179
+ // Run after animations complete
180
+ function Screen() {
181
+ useEffect(() => {
182
+ const task = InteractionManager.runAfterInteractions(() => {
183
+ // Expensive operation
184
+ loadHeavyData();
185
+ });
186
+
187
+ return () => task.cancel();
188
+ }, []);
189
+ }
190
+
191
+ // Or use startTransition
192
+ import { startTransition } from 'react';
193
+
194
+ function SearchInput() {
195
+ const [query, setQuery] = useState('');
196
+
197
+ const handleChange = (text: string) => {
198
+ setQuery(text); // Urgent - update input
199
+
200
+ startTransition(() => {
201
+ // Non-urgent - can be interrupted
202
+ setSearchResults(search(text));
203
+ });
204
+ };
205
+ }
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Animations
211
+
212
+ ### PERF-009: Use native driver
213
+
214
+ ```typescript
215
+ import Animated, {
216
+ useAnimatedStyle,
217
+ withSpring,
218
+ useSharedValue,
219
+ } from 'react-native-reanimated';
220
+
221
+ function AnimatedCard() {
222
+ const scale = useSharedValue(1);
223
+
224
+ const animatedStyle = useAnimatedStyle(() => ({
225
+ transform: [{ scale: scale.value }],
226
+ }));
227
+
228
+ const handlePressIn = () => {
229
+ scale.value = withSpring(0.95);
230
+ };
231
+
232
+ const handlePressOut = () => {
233
+ scale.value = withSpring(1);
234
+ };
235
+
236
+ return (
237
+ <Pressable onPressIn={handlePressIn} onPressOut={handlePressOut}>
238
+ <Animated.View style={animatedStyle}>
239
+ <Text>Card</Text>
240
+ </Animated.View>
241
+ </Pressable>
242
+ );
243
+ }
244
+ ```
245
+
246
+ ### PERF-010: Avoid layout animations
247
+
248
+ ```typescript
249
+ // BAD - Triggers layout (slow)
250
+ const animatedStyle = useAnimatedStyle(() => ({
251
+ width: width.value, // Layout property
252
+ height: height.value, // Layout property
253
+ marginTop: margin.value, // Layout property
254
+ }));
255
+
256
+ // GOOD - Transform only (fast, native thread)
257
+ const animatedStyle = useAnimatedStyle(() => ({
258
+ transform: [
259
+ { translateX: x.value },
260
+ { translateY: y.value },
261
+ { scale: scale.value },
262
+ { rotate: `${rotation.value}deg` },
263
+ ],
264
+ opacity: opacity.value,
265
+ }));
266
+ ```
267
+
268
+ ---
269
+
270
+ ## Data Loading
271
+
272
+ ### PERF-011: Prefetch data
273
+
274
+ ```typescript
275
+ import { useQueryClient } from '@tanstack/react-query';
276
+ import { Link } from 'expo-router';
277
+
278
+ function UserListItem({ user }) {
279
+ const queryClient = useQueryClient();
280
+
281
+ // Prefetch on press-in (before navigation)
282
+ const handlePressIn = () => {
283
+ queryClient.prefetchQuery({
284
+ queryKey: ['user', user.id],
285
+ queryFn: () => fetchUser(user.id),
286
+ });
287
+ };
288
+
289
+ return (
290
+ <Link href={`/users/${user.id}`} asChild>
291
+ <Pressable onPressIn={handlePressIn}>
292
+ <Text>{user.name}</Text>
293
+ </Pressable>
294
+ </Link>
295
+ );
296
+ }
297
+ ```
298
+
299
+ ### PERF-012: Pagination
300
+
301
+ ```typescript
302
+ import { useInfiniteQuery } from '@tanstack/react-query';
303
+
304
+ function usePaginatedPosts() {
305
+ return useInfiniteQuery({
306
+ queryKey: ['posts'],
307
+ queryFn: ({ pageParam = 1 }) => fetchPosts(pageParam),
308
+ getNextPageParam: (lastPage) => lastPage.nextPage,
309
+ initialPageParam: 1,
310
+ });
311
+ }
312
+
313
+ function PostList() {
314
+ const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = usePaginatedPosts();
315
+
316
+ const posts = data?.pages.flatMap(page => page.items) ?? [];
317
+
318
+ return (
319
+ <FlashList
320
+ data={posts}
321
+ renderItem={renderPost}
322
+ onEndReached={() => hasNextPage && fetchNextPage()}
323
+ onEndReachedThreshold={0.5}
324
+ ListFooterComponent={isFetchingNextPage ? <Spinner /> : null}
325
+ estimatedItemSize={100}
326
+ />
327
+ );
328
+ }
329
+ ```
330
+
331
+ ---
332
+
333
+ ## Bundle Size
334
+
335
+ ### PERF-013: Tree-shake imports
336
+
337
+ ```typescript
338
+ // BAD - Imports entire library
339
+ import { format } from 'date-fns';
340
+ import _ from 'lodash';
341
+
342
+ // GOOD - Specific imports
343
+ import format from 'date-fns/format';
344
+ import debounce from 'lodash/debounce';
345
+ ```
346
+
347
+ ### PERF-014: Lazy load screens
348
+
349
+ ```typescript
350
+ // Heavy screens loaded on demand
351
+ import { lazy } from 'react';
352
+
353
+ const HeavyEditor = lazy(() => import('./HeavyEditor'));
354
+
355
+ function Screen() {
356
+ const [showEditor, setShowEditor] = useState(false);
357
+
358
+ return (
359
+ <View>
360
+ <Button onPress={() => setShowEditor(true)}>Open Editor</Button>
361
+ {showEditor && (
362
+ <Suspense fallback={<Spinner />}>
363
+ <HeavyEditor />
364
+ </Suspense>
365
+ )}
366
+ </View>
367
+ );
368
+ }
369
+ ```
370
+
371
+ ---
372
+
373
+ ## Profiling
374
+
375
+ ### PERF-015: Measure performance
376
+
377
+ ```typescript
378
+ // Console timing
379
+ console.time('render');
380
+ // ... operation
381
+ console.timeEnd('render');
382
+
383
+ // React DevTools Profiler
384
+ import { Profiler } from 'react';
385
+
386
+ function onRenderCallback(id, phase, actualDuration) {
387
+ console.log(`${id} ${phase}: ${actualDuration}ms`);
388
+ }
389
+
390
+ <Profiler id="UserList" onRender={onRenderCallback}>
391
+ <UserList />
392
+ </Profiler>
393
+
394
+ // Flipper for detailed profiling
395
+ // Use React Native Performance Monitor
396
+ ```
397
+
398
+ ### PERF-016: Monitor in production
399
+
400
+ ```typescript
401
+ // Track slow renders
402
+ import * as Sentry from '@sentry/react-native';
403
+
404
+ Sentry.init({
405
+ tracesSampleRate: 0.1,
406
+ enableAutoPerformanceTracking: true,
407
+ });
408
+
409
+ // Custom spans
410
+ const transaction = Sentry.startTransaction({ name: 'loadUsers' });
411
+ const span = transaction.startChild({ op: 'fetch' });
412
+ await fetchUsers();
413
+ span.finish();
414
+ transaction.finish();
415
+ ```