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,427 @@
1
+ # Critical Rules - Expo/React Native
2
+
3
+ Must-follow rules. Violations block PR merge.
4
+
5
+ ---
6
+
7
+ ## Component Patterns
8
+
9
+ ### RN-001: Use correct components
10
+
11
+ ```typescript
12
+ // BAD - Web components don't work
13
+ <div className="container">
14
+ <span>Text</span>
15
+ <img src={url} />
16
+
17
+ // GOOD - React Native components
18
+ <View className="container">
19
+ <Text>Text content</Text>
20
+ <Image source={{ uri: url }} />
21
+
22
+ // Text must be wrapped
23
+ // BAD
24
+ <View>Hello World</View>
25
+
26
+ // GOOD
27
+ <View><Text>Hello World</Text></View>
28
+ ```
29
+
30
+ ### RN-002: Handle text properly
31
+
32
+ ```typescript
33
+ // All text must be in Text component
34
+ // BAD
35
+ <View>{user.name}</View>
36
+
37
+ // GOOD
38
+ <View><Text>{user.name}</Text></View>
39
+
40
+ // Nested text is OK
41
+ <Text>
42
+ Hello <Text className="font-bold">{name}</Text>!
43
+ </Text>
44
+
45
+ // String interpolation OK in Text
46
+ <Text>{`Welcome, ${name}`}</Text>
47
+ ```
48
+
49
+ ### RN-003: Use Pressable for touch
50
+
51
+ ```typescript
52
+ // GOOD - Pressable with feedback
53
+ <Pressable
54
+ onPress={handlePress}
55
+ className="active:opacity-70"
56
+ hitSlop={8} // Increase touch target
57
+ >
58
+ <Text>Tap me</Text>
59
+ </Pressable>
60
+
61
+ // With proper states
62
+ <Pressable
63
+ onPress={handlePress}
64
+ className={({ pressed }) =>
65
+ `p-4 rounded-lg ${pressed ? 'bg-gray-200' : 'bg-white'}`
66
+ }
67
+ >
68
+ {({ pressed }) => (
69
+ <Text className={pressed ? 'text-gray-600' : 'text-black'}>
70
+ Tap me
71
+ </Text>
72
+ )}
73
+ </Pressable>
74
+
75
+ // Avoid TouchableOpacity (deprecated feel)
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Platform Safety
81
+
82
+ ### RN-004: Handle platform differences
83
+
84
+ ```typescript
85
+ import { Platform } from 'react-native';
86
+
87
+ // Platform-specific code
88
+ if (Platform.OS === 'ios') {
89
+ // iOS only
90
+ }
91
+
92
+ if (Platform.OS === 'android') {
93
+ // Android only
94
+ }
95
+
96
+ // Platform.select for values
97
+ const styles = {
98
+ shadow: Platform.select({
99
+ ios: {
100
+ shadowColor: '#000',
101
+ shadowOffset: { width: 0, height: 2 },
102
+ shadowOpacity: 0.1,
103
+ shadowRadius: 4,
104
+ },
105
+ android: {
106
+ elevation: 4,
107
+ },
108
+ }),
109
+ };
110
+ ```
111
+
112
+ ### RN-005: Safe area handling
113
+
114
+ ```typescript
115
+ import { SafeAreaView } from 'react-native-safe-area-context';
116
+
117
+ // Wrap screens that need safe area
118
+ export default function HomeScreen() {
119
+ return (
120
+ <SafeAreaView className="flex-1 bg-white" edges={['top']}>
121
+ <ScrollView>
122
+ {/* Content */}
123
+ </ScrollView>
124
+ </SafeAreaView>
125
+ );
126
+ }
127
+
128
+ // Or use safe area hooks
129
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
130
+
131
+ function Header() {
132
+ const insets = useSafeAreaInsets();
133
+ return (
134
+ <View style={{ paddingTop: insets.top }}>
135
+ {/* Header content */}
136
+ </View>
137
+ );
138
+ }
139
+ ```
140
+
141
+ ### RN-006: Keyboard handling
142
+
143
+ ```typescript
144
+ import { KeyboardAvoidingView, Platform } from 'react-native';
145
+
146
+ function LoginScreen() {
147
+ return (
148
+ <KeyboardAvoidingView
149
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
150
+ className="flex-1"
151
+ >
152
+ <ScrollView keyboardShouldPersistTaps="handled">
153
+ <TextInput placeholder="Email" />
154
+ <TextInput placeholder="Password" secureTextEntry />
155
+ <Button title="Login" onPress={handleLogin} />
156
+ </ScrollView>
157
+ </KeyboardAvoidingView>
158
+ );
159
+ }
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Performance
165
+
166
+ ### RN-007: Avoid inline styles in lists
167
+
168
+ ```typescript
169
+ // BAD - Creates new object every render
170
+ <FlatList
171
+ data={items}
172
+ renderItem={({ item }) => (
173
+ <View style={{ padding: 16, margin: 8 }}> {/* New object! */}
174
+ <Text>{item.name}</Text>
175
+ </View>
176
+ )}
177
+ />
178
+
179
+ // GOOD - Use className or StyleSheet
180
+ <FlatList
181
+ data={items}
182
+ renderItem={({ item }) => (
183
+ <View className="p-4 m-2">
184
+ <Text>{item.name}</Text>
185
+ </View>
186
+ )}
187
+ />
188
+
189
+ // Or memoized styles
190
+ const styles = StyleSheet.create({
191
+ item: { padding: 16, margin: 8 },
192
+ });
193
+ ```
194
+
195
+ ### RN-008: Use FlashList for long lists
196
+
197
+ ```typescript
198
+ import { FlashList } from '@shopify/flash-list';
199
+
200
+ // GOOD - Better performance than FlatList
201
+ <FlashList
202
+ data={items}
203
+ keyExtractor={(item) => item.id}
204
+ renderItem={({ item }) => <ItemCard item={item} />}
205
+ estimatedItemSize={80} // Required!
206
+ />
207
+
208
+ // FlatList OK for short lists (<50 items)
209
+ ```
210
+
211
+ ### RN-009: Memoize expensive renders
212
+
213
+ ```typescript
214
+ import { memo, useCallback, useMemo } from 'react';
215
+
216
+ // Memoize list items
217
+ const ItemCard = memo(function ItemCard({ item, onPress }) {
218
+ return (
219
+ <Pressable onPress={() => onPress(item.id)}>
220
+ <Text>{item.name}</Text>
221
+ </Pressable>
222
+ );
223
+ });
224
+
225
+ // Memoize callbacks
226
+ function ItemList({ items }) {
227
+ const handlePress = useCallback((id: string) => {
228
+ router.push(`/items/${id}`);
229
+ }, []);
230
+
231
+ // Memoize computed values
232
+ const sortedItems = useMemo(
233
+ () => [...items].sort((a, b) => a.name.localeCompare(b.name)),
234
+ [items]
235
+ );
236
+
237
+ return (
238
+ <FlashList
239
+ data={sortedItems}
240
+ renderItem={({ item }) => (
241
+ <ItemCard item={item} onPress={handlePress} />
242
+ )}
243
+ />
244
+ );
245
+ }
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Security
251
+
252
+ ### RN-010: Secure storage for sensitive data
253
+
254
+ ```typescript
255
+ // BAD - AsyncStorage for tokens
256
+ import AsyncStorage from '@react-native-async-storage/async-storage';
257
+ await AsyncStorage.setItem('token', token); // Not encrypted!
258
+
259
+ // GOOD - SecureStore for sensitive data
260
+ import * as SecureStore from 'expo-secure-store';
261
+ await SecureStore.setItemAsync('token', token); // Encrypted
262
+
263
+ // Use AsyncStorage only for non-sensitive data
264
+ await AsyncStorage.setItem('theme', 'dark'); // OK
265
+ await AsyncStorage.setItem('onboarded', 'true'); // OK
266
+ ```
267
+
268
+ ### RN-011: Validate deep links
269
+
270
+ ```typescript
271
+ // app.json
272
+ {
273
+ "expo": {
274
+ "scheme": "myapp"
275
+ }
276
+ }
277
+
278
+ // Validate incoming links
279
+ import { useURL } from 'expo-linking';
280
+
281
+ function DeepLinkHandler() {
282
+ const url = useURL();
283
+
284
+ useEffect(() => {
285
+ if (url) {
286
+ const parsed = Linking.parse(url);
287
+
288
+ // Validate before navigating
289
+ if (isValidPath(parsed.path)) {
290
+ router.push(parsed.path);
291
+ }
292
+ }
293
+ }, [url]);
294
+ }
295
+ ```
296
+
297
+ ### RN-012: Never hardcode secrets
298
+
299
+ ```typescript
300
+ // BAD
301
+ const API_KEY = 'sk_live_xxxxx';
302
+
303
+ // GOOD - Use environment variables
304
+ // app.config.js
305
+ export default {
306
+ expo: {
307
+ extra: {
308
+ apiUrl: process.env.API_URL,
309
+ },
310
+ },
311
+ };
312
+
313
+ // Access via Constants
314
+ import Constants from 'expo-constants';
315
+ const apiUrl = Constants.expoConfig?.extra?.apiUrl;
316
+ ```
317
+
318
+ ---
319
+
320
+ ## Accessibility
321
+
322
+ ### RN-013: Add accessibility labels
323
+
324
+ ```typescript
325
+ <Pressable
326
+ onPress={handleDelete}
327
+ accessibilityLabel="Delete item"
328
+ accessibilityRole="button"
329
+ accessibilityHint="Removes this item from your list"
330
+ >
331
+ <TrashIcon />
332
+ </Pressable>
333
+
334
+ <Image
335
+ source={{ uri: user.avatar }}
336
+ accessibilityLabel={`Profile picture of ${user.name}`}
337
+ />
338
+
339
+ // For decorative elements
340
+ <Image
341
+ source={decorativeImage}
342
+ accessibilityElementsHidden={true}
343
+ />
344
+ ```
345
+
346
+ ### RN-014: Support screen readers
347
+
348
+ ```typescript
349
+ // Group related elements
350
+ <View accessibilityRole="summary">
351
+ <Text>Order Total</Text>
352
+ <Text>${total}</Text>
353
+ </View>
354
+
355
+ // Live regions for updates
356
+ <View
357
+ accessibilityLiveRegion="polite"
358
+ accessibilityLabel={`${count} items in cart`}
359
+ >
360
+ <Text>{count}</Text>
361
+ </View>
362
+
363
+ // State changes
364
+ <Pressable
365
+ accessibilityState={{ selected: isSelected }}
366
+ accessibilityRole="checkbox"
367
+ >
368
+ <Text>Option {isSelected ? '(selected)' : ''}</Text>
369
+ </Pressable>
370
+ ```
371
+
372
+ ---
373
+
374
+ ## Error Handling
375
+
376
+ ### RN-015: Handle errors gracefully
377
+
378
+ ```typescript
379
+ import { ErrorBoundary } from 'react-error-boundary';
380
+
381
+ function ErrorFallback({ error, resetErrorBoundary }) {
382
+ return (
383
+ <View className="flex-1 items-center justify-center p-4">
384
+ <Text className="text-lg font-bold text-red-500">
385
+ Something went wrong
386
+ </Text>
387
+ <Text className="text-gray-600 mt-2">{error.message}</Text>
388
+ <Pressable
389
+ onPress={resetErrorBoundary}
390
+ className="mt-4 bg-blue-500 px-4 py-2 rounded"
391
+ >
392
+ <Text className="text-white">Try Again</Text>
393
+ </Pressable>
394
+ </View>
395
+ );
396
+ }
397
+
398
+ // Wrap screens
399
+ <ErrorBoundary FallbackComponent={ErrorFallback}>
400
+ <HomeScreen />
401
+ </ErrorBoundary>
402
+ ```
403
+
404
+ ### RN-016: Handle network errors
405
+
406
+ ```typescript
407
+ import NetInfo from '@react-native-community/netinfo';
408
+
409
+ function useNetworkStatus() {
410
+ const [isConnected, setIsConnected] = useState(true);
411
+
412
+ useEffect(() => {
413
+ return NetInfo.addEventListener((state) => {
414
+ setIsConnected(state.isConnected ?? true);
415
+ });
416
+ }, []);
417
+
418
+ return isConnected;
419
+ }
420
+
421
+ // In components
422
+ const isConnected = useNetworkStatus();
423
+
424
+ if (!isConnected) {
425
+ return <OfflineScreen />;
426
+ }
427
+ ```