tribunal-kit 2.4.6 → 3.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.
- package/.agent/ARCHITECTURE.md +99 -99
- package/.agent/GEMINI.md +52 -52
- package/.agent/agents/accessibility-reviewer.md +139 -86
- package/.agent/agents/ai-code-reviewer.md +160 -90
- package/.agent/agents/backend-specialist.md +164 -127
- package/.agent/agents/code-archaeologist.md +115 -73
- package/.agent/agents/database-architect.md +130 -110
- package/.agent/agents/debugger.md +137 -97
- package/.agent/agents/dependency-reviewer.md +78 -30
- package/.agent/agents/devops-engineer.md +161 -118
- package/.agent/agents/documentation-writer.md +151 -87
- package/.agent/agents/explorer-agent.md +117 -99
- package/.agent/agents/frontend-reviewer.md +127 -47
- package/.agent/agents/frontend-specialist.md +169 -109
- package/.agent/agents/game-developer.md +28 -164
- package/.agent/agents/logic-reviewer.md +87 -49
- package/.agent/agents/mobile-developer.md +151 -103
- package/.agent/agents/mobile-reviewer.md +133 -50
- package/.agent/agents/orchestrator.md +121 -110
- package/.agent/agents/penetration-tester.md +103 -77
- package/.agent/agents/performance-optimizer.md +136 -92
- package/.agent/agents/performance-reviewer.md +139 -69
- package/.agent/agents/product-manager.md +104 -70
- package/.agent/agents/product-owner.md +6 -25
- package/.agent/agents/project-planner.md +95 -95
- package/.agent/agents/qa-automation-engineer.md +174 -87
- package/.agent/agents/security-auditor.md +133 -129
- package/.agent/agents/seo-specialist.md +160 -99
- package/.agent/agents/sql-reviewer.md +132 -44
- package/.agent/agents/supervisor-agent.md +137 -109
- package/.agent/agents/swarm-worker-contracts.md +17 -17
- package/.agent/agents/swarm-worker-registry.md +46 -46
- package/.agent/agents/test-coverage-reviewer.md +132 -53
- package/.agent/agents/test-engineer.md +0 -21
- package/.agent/agents/type-safety-reviewer.md +143 -33
- package/.agent/patterns/generator.md +9 -9
- package/.agent/patterns/inversion.md +12 -12
- package/.agent/patterns/pipeline.md +9 -9
- package/.agent/patterns/reviewer.md +13 -13
- package/.agent/patterns/tool-wrapper.md +9 -9
- package/.agent/rules/GEMINI.md +63 -63
- package/.agent/scripts/__pycache__/auto_preview.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/bundle_analyzer.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/checklist.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/dependency_analyzer.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/session_manager.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/skill_integrator.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/swarm_dispatcher.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
- package/.agent/scripts/__pycache__/verify_all.cpython-311.pyc +0 -0
- package/.agent/scripts/compress_skills.py +167 -0
- package/.agent/scripts/consolidate_skills.py +173 -0
- package/.agent/scripts/deep_compress.py +202 -0
- package/.agent/scripts/minify_context.py +80 -0
- package/.agent/scripts/security_scan.py +1 -1
- package/.agent/scripts/strip_tribunal.py +41 -0
- package/.agent/skills/agent-organizer/SKILL.md +60 -100
- package/.agent/skills/agentic-patterns/SKILL.md +0 -70
- package/.agent/skills/ai-prompt-injection-defense/SKILL.md +108 -53
- package/.agent/skills/api-patterns/SKILL.md +197 -257
- package/.agent/skills/api-security-auditor/SKILL.md +125 -57
- package/.agent/skills/app-builder/SKILL.md +326 -50
- package/.agent/skills/app-builder/templates/SKILL.md +13 -15
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +16 -16
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +22 -22
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +18 -18
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +20 -20
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +17 -17
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +18 -18
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +21 -21
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +19 -19
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +26 -26
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +26 -26
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +19 -19
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +18 -18
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +20 -20
- package/.agent/skills/appflow-wireframe/SKILL.md +71 -98
- package/.agent/skills/architecture/SKILL.md +161 -200
- package/.agent/skills/authentication-best-practices/SKILL.md +121 -54
- package/.agent/skills/bash-linux/SKILL.md +71 -166
- package/.agent/skills/behavioral-modes/SKILL.md +8 -69
- package/.agent/skills/brainstorming/SKILL.md +345 -127
- package/.agent/skills/building-native-ui/SKILL.md +125 -57
- package/.agent/skills/clean-code/SKILL.md +266 -149
- package/.agent/skills/code-review-checklist/SKILL.md +0 -62
- package/.agent/skills/config-validator/SKILL.md +73 -131
- package/.agent/skills/csharp-developer/SKILL.md +434 -73
- package/.agent/skills/database-design/SKILL.md +190 -275
- package/.agent/skills/deployment-procedures/SKILL.md +81 -158
- package/.agent/skills/devops-engineer/SKILL.md +255 -94
- package/.agent/skills/devops-incident-responder/SKILL.md +50 -69
- package/.agent/skills/doc.md +5 -5
- package/.agent/skills/documentation-templates/SKILL.md +19 -63
- package/.agent/skills/edge-computing/SKILL.md +75 -165
- package/.agent/skills/extract-design-system/SKILL.md +84 -58
- package/.agent/skills/framer-motion-expert/SKILL.md +195 -0
- package/.agent/skills/frontend-design/SKILL.md +151 -499
- package/.agent/skills/game-design-expert/SKILL.md +71 -0
- package/.agent/skills/game-engineering-expert/SKILL.md +88 -0
- package/.agent/skills/geo-fundamentals/SKILL.md +52 -178
- package/.agent/skills/github-operations/SKILL.md +197 -272
- package/.agent/skills/gsap-expert/SKILL.md +194 -0
- package/.agent/skills/i18n-localization/SKILL.md +60 -172
- package/.agent/skills/intelligent-routing/SKILL.md +123 -103
- package/.agent/skills/lint-and-validate/SKILL.md +8 -52
- package/.agent/skills/llm-engineering/SKILL.md +281 -195
- package/.agent/skills/local-first/SKILL.md +76 -159
- package/.agent/skills/mcp-builder/SKILL.md +48 -188
- package/.agent/skills/mobile-design/SKILL.md +213 -219
- package/.agent/skills/motion-engineering/SKILL.md +184 -0
- package/.agent/skills/nextjs-react-expert/SKILL.md +184 -203
- package/.agent/skills/nodejs-best-practices/SKILL.md +403 -185
- package/.agent/skills/observability/SKILL.md +211 -203
- package/.agent/skills/parallel-agents/SKILL.md +53 -146
- package/.agent/skills/performance-profiling/SKILL.md +171 -151
- package/.agent/skills/plan-writing/SKILL.md +49 -153
- package/.agent/skills/platform-engineer/SKILL.md +57 -103
- package/.agent/skills/playwright-best-practices/SKILL.md +110 -63
- package/.agent/skills/powershell-windows/SKILL.md +61 -179
- package/.agent/skills/python-patterns/SKILL.md +7 -35
- package/.agent/skills/python-pro/SKILL.md +273 -114
- package/.agent/skills/react-specialist/SKILL.md +227 -108
- package/.agent/skills/readme-builder/SKILL.md +15 -85
- package/.agent/skills/realtime-patterns/SKILL.md +216 -243
- package/.agent/skills/red-team-tactics/SKILL.md +10 -51
- package/.agent/skills/rust-pro/SKILL.md +525 -142
- package/.agent/skills/seo-fundamentals/SKILL.md +92 -153
- package/.agent/skills/server-management/SKILL.md +110 -166
- package/.agent/skills/shadcn-ui-expert/SKILL.md +154 -55
- package/.agent/skills/skill-creator/SKILL.md +18 -58
- package/.agent/skills/sql-pro/SKILL.md +543 -68
- package/.agent/skills/supabase-postgres-best-practices/SKILL.md +28 -68
- package/.agent/skills/swiftui-expert/SKILL.md +124 -57
- package/.agent/skills/systematic-debugging/SKILL.md +49 -151
- package/.agent/skills/tailwind-patterns/SKILL.md +433 -149
- package/.agent/skills/tdd-workflow/SKILL.md +63 -169
- package/.agent/skills/test-result-analyzer/SKILL.md +33 -73
- package/.agent/skills/testing-patterns/SKILL.md +437 -130
- package/.agent/skills/trend-researcher/SKILL.md +30 -71
- package/.agent/skills/ui-ux-pro-max/SKILL.md +0 -41
- package/.agent/skills/ui-ux-researcher/SKILL.md +51 -91
- package/.agent/skills/vue-expert/SKILL.md +225 -119
- package/.agent/skills/vulnerability-scanner/SKILL.md +264 -226
- package/.agent/skills/web-accessibility-auditor/SKILL.md +141 -58
- package/.agent/skills/web-design-guidelines/SKILL.md +17 -61
- package/.agent/skills/webapp-testing/SKILL.md +71 -196
- package/.agent/skills/whimsy-injector/SKILL.md +58 -132
- package/.agent/skills/workflow-optimizer/SKILL.md +28 -68
- package/.agent/workflows/api-tester.md +96 -224
- package/.agent/workflows/audit.md +81 -122
- package/.agent/workflows/brainstorm.md +69 -105
- package/.agent/workflows/changelog.md +65 -97
- package/.agent/workflows/create.md +73 -88
- package/.agent/workflows/debug.md +80 -111
- package/.agent/workflows/deploy.md +119 -92
- package/.agent/workflows/enhance.md +80 -91
- package/.agent/workflows/fix.md +68 -97
- package/.agent/workflows/generate.md +165 -164
- package/.agent/workflows/migrate.md +106 -109
- package/.agent/workflows/orchestrate.md +103 -86
- package/.agent/workflows/performance-benchmarker.md +77 -268
- package/.agent/workflows/plan.md +120 -98
- package/.agent/workflows/preview.md +39 -96
- package/.agent/workflows/refactor.md +105 -97
- package/.agent/workflows/review-ai.md +63 -102
- package/.agent/workflows/review.md +71 -110
- package/.agent/workflows/session.md +53 -113
- package/.agent/workflows/status.md +42 -88
- package/.agent/workflows/strengthen-skills.md +90 -51
- package/.agent/workflows/swarm.md +114 -129
- package/.agent/workflows/test.md +125 -102
- package/.agent/workflows/tribunal-backend.md +60 -78
- package/.agent/workflows/tribunal-database.md +62 -100
- package/.agent/workflows/tribunal-frontend.md +62 -82
- package/.agent/workflows/tribunal-full.md +56 -100
- package/.agent/workflows/tribunal-mobile.md +65 -94
- package/.agent/workflows/tribunal-performance.md +62 -105
- package/.agent/workflows/ui-ux-pro-max.md +72 -121
- package/README.md +11 -15
- package/package.json +1 -1
- package/.agent/skills/api-patterns/api-style.md +0 -42
- package/.agent/skills/api-patterns/auth.md +0 -24
- package/.agent/skills/api-patterns/documentation.md +0 -26
- package/.agent/skills/api-patterns/graphql.md +0 -41
- package/.agent/skills/api-patterns/rate-limiting.md +0 -31
- package/.agent/skills/api-patterns/response.md +0 -37
- package/.agent/skills/api-patterns/rest.md +0 -40
- package/.agent/skills/api-patterns/security-testing.md +0 -122
- package/.agent/skills/api-patterns/trpc.md +0 -41
- package/.agent/skills/api-patterns/versioning.md +0 -22
- package/.agent/skills/app-builder/agent-coordination.md +0 -71
- package/.agent/skills/app-builder/feature-building.md +0 -53
- package/.agent/skills/app-builder/project-detection.md +0 -34
- package/.agent/skills/app-builder/scaffolding.md +0 -118
- package/.agent/skills/app-builder/tech-stack.md +0 -40
- package/.agent/skills/architecture/context-discovery.md +0 -43
- package/.agent/skills/architecture/examples.md +0 -94
- package/.agent/skills/architecture/pattern-selection.md +0 -68
- package/.agent/skills/architecture/patterns-reference.md +0 -50
- package/.agent/skills/architecture/trade-off-analysis.md +0 -77
- package/.agent/skills/brainstorming/dynamic-questioning.md +0 -360
- package/.agent/skills/database-design/database-selection.md +0 -43
- package/.agent/skills/database-design/indexing.md +0 -39
- package/.agent/skills/database-design/migrations.md +0 -48
- package/.agent/skills/database-design/optimization.md +0 -36
- package/.agent/skills/database-design/orm-selection.md +0 -30
- package/.agent/skills/database-design/schema-design.md +0 -56
- package/.agent/skills/dotnet-core-expert/SKILL.md +0 -103
- package/.agent/skills/framer-motion-animations/SKILL.md +0 -74
- package/.agent/skills/frontend-design/animation-guide.md +0 -331
- package/.agent/skills/frontend-design/color-system.md +0 -329
- package/.agent/skills/frontend-design/decision-trees.md +0 -418
- package/.agent/skills/frontend-design/motion-graphics.md +0 -306
- package/.agent/skills/frontend-design/typography-system.md +0 -363
- package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
- package/.agent/skills/frontend-design/visual-effects.md +0 -383
- package/.agent/skills/game-development/2d-games/SKILL.md +0 -119
- package/.agent/skills/game-development/3d-games/SKILL.md +0 -135
- package/.agent/skills/game-development/SKILL.md +0 -236
- package/.agent/skills/game-development/game-art/SKILL.md +0 -185
- package/.agent/skills/game-development/game-audio/SKILL.md +0 -190
- package/.agent/skills/game-development/game-design/SKILL.md +0 -129
- package/.agent/skills/game-development/mobile-games/SKILL.md +0 -108
- package/.agent/skills/game-development/multiplayer/SKILL.md +0 -132
- package/.agent/skills/game-development/pc-games/SKILL.md +0 -144
- package/.agent/skills/game-development/vr-ar/SKILL.md +0 -123
- package/.agent/skills/game-development/web-games/SKILL.md +0 -150
- package/.agent/skills/intelligent-routing/router-manifest.md +0 -65
- package/.agent/skills/mobile-design/decision-trees.md +0 -516
- package/.agent/skills/mobile-design/mobile-backend.md +0 -491
- package/.agent/skills/mobile-design/mobile-color-system.md +0 -420
- package/.agent/skills/mobile-design/mobile-debugging.md +0 -122
- package/.agent/skills/mobile-design/mobile-design-thinking.md +0 -357
- package/.agent/skills/mobile-design/mobile-navigation.md +0 -458
- package/.agent/skills/mobile-design/mobile-performance.md +0 -767
- package/.agent/skills/mobile-design/mobile-testing.md +0 -356
- package/.agent/skills/mobile-design/mobile-typography.md +0 -433
- package/.agent/skills/mobile-design/platform-android.md +0 -666
- package/.agent/skills/mobile-design/platform-ios.md +0 -561
- package/.agent/skills/mobile-design/touch-psychology.md +0 -537
- package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +0 -312
- package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +0 -240
- package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +0 -490
- package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +0 -264
- package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +0 -581
- package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +0 -432
- package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +0 -684
- package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +0 -150
- package/.agent/skills/vulnerability-scanner/checklists.md +0 -121
|
@@ -1,75 +1,143 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: building-native-ui
|
|
3
|
-
description: Cross-platform
|
|
4
|
-
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
-
version:
|
|
6
|
-
last-updated: 2026-
|
|
7
|
-
applies-to-model: claude-3-7-sonnet
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Building Native UI (React Native / Expo)
|
|
11
|
-
|
|
12
|
-
You are an expert Mobile Frontend Engineer. You understand the profound differences between building a website and building a fluid, responsive native application for iOS and Android.
|
|
13
|
-
|
|
14
|
-
## Core Directives
|
|
15
|
-
|
|
16
|
-
1. **Environmental Safety First:**
|
|
17
|
-
- Always wrap root navigational components or edge-touching screens in `SafeAreaView` (from `react-native-safe-area-context`).
|
|
18
|
-
- Any screen containing text inputs MUST utilize `KeyboardAvoidingView` or `KeyboardAwareScrollView` to prevent the software keyboard from occluding input fields.
|
|
19
|
-
|
|
20
|
-
2. **Platform Tropes:**
|
|
21
|
-
- Rely heavily on `Platform.OS` or `Platform.select()` to gracefully adapt UI components.
|
|
22
|
-
- Shadows on iOS (`shadowOpacity`, `shadowRadius`) do not work the same stringently on Android (`elevation`). Provide robust fallback implementations to both.
|
|
23
|
-
|
|
24
|
-
3. **Performance Boundaries:**
|
|
25
|
-
- Never use deeply generic or unbound nested `.map()` loops for massive UI layouts. Always use `FlatList` or `FlashList` for heavy lists to optimize memory via view recycling.
|
|
26
|
-
- Avoid massive functional component re-renders. Use standard `useMemo` strictly for expensive list data formatting.
|
|
27
|
-
|
|
28
|
-
4. **Animations & Gestures:**
|
|
29
|
-
- Use `react-native-reanimated` instead of standard `Animated` for anything complex. Run animations completely natively on the UI thread without dropping JS bridge frames.
|
|
30
|
-
- Pair interactive swipes/drags directly with `react-native-gesture-handler`.
|
|
31
|
-
|
|
32
|
-
## Execution
|
|
33
|
-
When outputting React Native application markup, always default to importing high-performance primitives (`Pressable` over `TouchableOpacity`, `FlashList` over `ScrollView(map)`).
|
|
1
|
+
---
|
|
2
|
+
name: building-native-ui
|
|
3
|
+
description: Cross-platform Native UI mastery (React Native / Expo). Building seamless, 60fps mobile interfaces, handling safe areas, navigation architectures (Expo Router), native modules, gestures/animations (Reanimated), and platform-specific styling. Use when building React Native or Expo mobile apps.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
+
version: 2.0.0
|
|
6
|
+
last-updated: 2026-04-02
|
|
7
|
+
applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
|
|
8
|
+
---
|
|
34
9
|
|
|
10
|
+
# Building Native UI — React Native & Expo Mastery
|
|
11
|
+
|
|
12
|
+
A mobile app isn't a website confined to a small screen.
|
|
13
|
+
60 FPS is not a goal; it is a rigid requirement. The JS thread is a fragile bottleneck.
|
|
35
14
|
|
|
36
15
|
---
|
|
37
16
|
|
|
38
|
-
##
|
|
17
|
+
## 1. The Expo Router Architecture
|
|
18
|
+
|
|
19
|
+
File-based routing replaces legacy imperative React Navigation boilerplates.
|
|
39
20
|
|
|
40
|
-
|
|
21
|
+
```typescript
|
|
22
|
+
// Directory structure dictates routes
|
|
23
|
+
// app/
|
|
24
|
+
// ├── _layout.tsx (Global wrap, e.g. Stack or Tabs)
|
|
25
|
+
// ├── index.tsx (Matches '/')
|
|
26
|
+
// ├── (auth)/ (Route group, invisible in URL)
|
|
27
|
+
// │ └── login.tsx (Matches '/login')
|
|
28
|
+
// └── user/
|
|
29
|
+
// └── [id].tsx (Dynamic route, matches '/user/123')
|
|
41
30
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
31
|
+
// Link navigation (Strongly typed in Expo Router v3+)
|
|
32
|
+
import { Link, router } from 'expo-router';
|
|
33
|
+
|
|
34
|
+
export default function Home() {
|
|
35
|
+
return (
|
|
36
|
+
<View>
|
|
37
|
+
{/* Declarative */}
|
|
38
|
+
<Link href="/user/123" asChild>
|
|
39
|
+
<Pressable><Text>Go to Profile</Text></Pressable>
|
|
40
|
+
</Link>
|
|
41
|
+
|
|
42
|
+
{/* Imperative */}
|
|
43
|
+
<Button onPress={() => router.push('/(auth)/login')} title="Login" />
|
|
44
|
+
</View>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
47
48
|
|
|
48
49
|
---
|
|
49
50
|
|
|
50
|
-
##
|
|
51
|
+
## 2. Platform Nuances & Safe Areas
|
|
52
|
+
|
|
53
|
+
Mobile devices have notches, home indicators, and varied status bars.
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
```typescript
|
|
56
|
+
// ❌ BAD: Ignoring notches
|
|
57
|
+
export const Header = () => <View style={{ paddingTop: 20 }} />
|
|
54
58
|
|
|
55
|
-
|
|
59
|
+
// ✅ GOOD: react-native-safe-area-context
|
|
60
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
export const Header = () => {
|
|
63
|
+
const insets = useSafeAreaInsets();
|
|
64
|
+
return (
|
|
65
|
+
<View style={{ paddingTop: insets.top, paddingBottom: insets.bottom }}>
|
|
66
|
+
<Text>Header Content</Text>
|
|
67
|
+
</View>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
60
70
|
|
|
61
|
-
|
|
71
|
+
// ✅ Platform-specific logic
|
|
72
|
+
import { Platform, StyleSheet } from 'react-native';
|
|
62
73
|
|
|
63
|
-
|
|
74
|
+
const styles = StyleSheet.create({
|
|
75
|
+
shadow: {
|
|
76
|
+
...Platform.select({
|
|
77
|
+
ios: { shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2 },
|
|
78
|
+
android: { elevation: 4 }, // Android requires elevation for shadows
|
|
79
|
+
}),
|
|
80
|
+
}
|
|
81
|
+
});
|
|
64
82
|
```
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 3. High-Performance Animations (Reanimated)
|
|
87
|
+
|
|
88
|
+
Never animate over the React Native bridge. Keep animations strictly on the native UI thread using `react-native-reanimated`.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// ❌ BAD: Animated.Value across the bridge, or setState driven animations
|
|
92
|
+
// setState -> JS Thread calculate -> Bridge JSON -> Native UI (Drops frames!)
|
|
93
|
+
|
|
94
|
+
// ✅ GOOD: Reanimated UI thread execution
|
|
95
|
+
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
|
|
96
|
+
|
|
97
|
+
export function BouncyBox() {
|
|
98
|
+
const offset = useSharedValue(0); // Lives natively
|
|
99
|
+
|
|
100
|
+
const animatedStyles = useAnimatedStyle(() => {
|
|
101
|
+
return {
|
|
102
|
+
transform: [{ translateY: offset.value }], // Syncs natively
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<>
|
|
108
|
+
<Animated.View style={[styles.box, animatedStyles]} />
|
|
109
|
+
<Button onPress={() => (offset.value = withSpring(Math.random() * 255))} title="Bounce" />
|
|
110
|
+
</>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
69
113
|
```
|
|
70
114
|
|
|
71
|
-
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 4. List Performance
|
|
118
|
+
|
|
119
|
+
FlatList rendering is the #1 cause of React Native app crashes due to OOM (Out of Memory).
|
|
72
120
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
121
|
+
```typescript
|
|
122
|
+
import { FlashList } from "@shopify/flash-list";
|
|
123
|
+
|
|
124
|
+
// ❌ BAD: Standard ScrollView for massive lists
|
|
125
|
+
// Maps every item instantly. Crashes on large data sets.
|
|
126
|
+
|
|
127
|
+
// ❌ MEDIOCRE: FlatList
|
|
128
|
+
// Blank spaces when scrolling fast due to JS thread bridge bottlenecks.
|
|
129
|
+
|
|
130
|
+
// ✅ BEST: FlashList (Shopify)
|
|
131
|
+
// Recycles views instantly like native UICollectionView / RecyclerView.
|
|
132
|
+
export function FastList({ data }) {
|
|
133
|
+
return (
|
|
134
|
+
<FlashList
|
|
135
|
+
data={data}
|
|
136
|
+
renderItem={({ item }) => <Text>{item.title}</Text>}
|
|
137
|
+
estimatedItemSize={50} // CRUCIAL for performance
|
|
138
|
+
/>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
@@ -1,206 +1,323 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clean-code
|
|
3
|
-
description:
|
|
3
|
+
description: Clean code mastery. Naming conventions, function design, DRY vs WET, SOLID principles with code examples, refactoring patterns, code smells detection, error handling philosophy, comments that add value, and the art of simplicity. Use when reviewing code quality, refactoring, or establishing coding standards.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
-
version:
|
|
6
|
-
last-updated: 2026-
|
|
5
|
+
version: 2.0.0
|
|
6
|
+
last-updated: 2026-04-01
|
|
7
7
|
applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
# Clean Code
|
|
11
|
-
|
|
12
|
-
> Code is read far more than it is written. Write for the next person.
|
|
13
|
-
> That person is often you, six months from now, confused.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Core Philosophy
|
|
18
|
-
|
|
19
|
-
Clean code is not aesthetic. It is functional. Messy code is slow to change, easy to break, and hard to debug. These standards exist to make code **safe to modify** — not to make it look clever.
|
|
10
|
+
# Clean Code — The Art of Readable Software
|
|
20
11
|
|
|
21
12
|
---
|
|
22
13
|
|
|
23
14
|
## Naming
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
**Rules:**
|
|
28
|
-
- Variables and functions describe what they hold or do — not how they do it
|
|
29
|
-
- Boolean names start with `is`, `has`, `can`, `should`
|
|
30
|
-
- No single-letter names except loop counters (`i`, `j`) and throwaway lambdas
|
|
31
|
-
- No abbreviations unless they are industry-wide (`url`, `id`, `dto`, `api`)
|
|
32
|
-
- Name at the right level of abstraction — `user` not `userObjectFromDatabase`
|
|
16
|
+
### Variables & Functions
|
|
33
17
|
|
|
34
|
-
```
|
|
35
|
-
// ❌
|
|
18
|
+
```typescript
|
|
19
|
+
// ❌ BAD: Cryptic, abbreviated, meaningless
|
|
36
20
|
const d = new Date();
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
21
|
+
const u = getU();
|
|
22
|
+
const flag = true;
|
|
23
|
+
function proc(x: number): number { return x * 1.08; }
|
|
24
|
+
|
|
25
|
+
// ✅ GOOD: Self-documenting, reveals intent
|
|
26
|
+
const registrationDate = new Date();
|
|
27
|
+
const currentUser = getCurrentUser();
|
|
28
|
+
const isEligibleForDiscount = true;
|
|
29
|
+
function addSalesTax(price: number): number { return price * 1.08; }
|
|
42
30
|
```
|
|
43
31
|
|
|
44
|
-
|
|
32
|
+
### Booleans
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
// ❌ BAD ✅ GOOD
|
|
36
|
+
const active = true; const isActive = true;
|
|
37
|
+
const admin = false; const hasAdminRole = false;
|
|
38
|
+
const loading = true; const isLoading = true;
|
|
39
|
+
const open = false; const isModalOpen = false;
|
|
40
|
+
const valid = true; const canSubmit = true;
|
|
41
|
+
|
|
42
|
+
// Boolean function names start with is/has/can/should
|
|
43
|
+
function isExpired(token: Token): boolean {}
|
|
44
|
+
function hasPermission(user: User, action: string): boolean {}
|
|
45
|
+
function canRetry(attempt: number): boolean {}
|
|
46
|
+
function shouldNotify(event: Event): boolean {}
|
|
47
|
+
```
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
### Constants & Enums
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
```typescript
|
|
52
|
+
// ❌ BAD: Magic numbers and strings
|
|
53
|
+
if (user.role === 3) { ... }
|
|
54
|
+
if (retries > 5) { ... }
|
|
55
|
+
const delay = 86400000;
|
|
49
56
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- Return early to avoid nesting — guard clauses before main logic
|
|
57
|
+
// ✅ GOOD: Named constants with meaning
|
|
58
|
+
const MAX_RETRY_ATTEMPTS = 5;
|
|
59
|
+
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
|
54
60
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
enum UserRole {
|
|
62
|
+
VIEWER = "viewer",
|
|
63
|
+
EDITOR = "editor",
|
|
64
|
+
ADMIN = "admin",
|
|
65
|
+
}
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
function createUserAndNotify(data: UserData) { ... }
|
|
67
|
+
if (user.role === UserRole.ADMIN) { ... }
|
|
68
|
+
if (retries > MAX_RETRY_ATTEMPTS) { ... }
|
|
62
69
|
```
|
|
63
70
|
|
|
64
71
|
---
|
|
65
72
|
|
|
66
|
-
##
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
const
|
|
73
|
+
## Function Design
|
|
74
|
+
|
|
75
|
+
### Small, Single-Purpose Functions
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// ❌ BAD: Does 5 things in one function
|
|
79
|
+
async function processOrder(order: Order) {
|
|
80
|
+
// validate
|
|
81
|
+
if (!order.items.length) throw new Error("Empty");
|
|
82
|
+
if (order.total < 0) throw new Error("Negative");
|
|
83
|
+
// calculate
|
|
84
|
+
const subtotal = order.items.reduce((sum, i) => sum + i.price * i.qty, 0);
|
|
85
|
+
const tax = subtotal * 0.08;
|
|
86
|
+
const total = subtotal + tax;
|
|
87
|
+
// save
|
|
88
|
+
await db.orders.insert({ ...order, total });
|
|
89
|
+
// notify
|
|
90
|
+
await emailService.send(order.userId, "Order placed");
|
|
91
|
+
// log
|
|
92
|
+
logger.info("Order processed", { orderId: order.id });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ✅ GOOD: Each function does one thing
|
|
96
|
+
async function processOrder(order: Order): Promise<ProcessedOrder> {
|
|
97
|
+
validateOrder(order);
|
|
98
|
+
const totals = calculateTotals(order.items);
|
|
99
|
+
const savedOrder = await saveOrder(order, totals);
|
|
100
|
+
await notifyCustomer(savedOrder);
|
|
101
|
+
return savedOrder;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function validateOrder(order: Order): void {
|
|
105
|
+
if (!order.items.length) throw new ValidationError("Order cannot be empty");
|
|
106
|
+
if (order.total < 0) throw new ValidationError("Total cannot be negative");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function calculateTotals(items: OrderItem[]): OrderTotals {
|
|
110
|
+
const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
111
|
+
const tax = subtotal * TAX_RATE;
|
|
112
|
+
return { subtotal, tax, total: subtotal + tax };
|
|
113
|
+
}
|
|
114
|
+
```
|
|
78
115
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
116
|
+
### Parameter Rules
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// ❌ BAD: Too many parameters
|
|
120
|
+
function createUser(
|
|
121
|
+
name: string, email: string, role: string,
|
|
122
|
+
isActive: boolean, avatar: string, bio: string
|
|
123
|
+
) { ... }
|
|
124
|
+
|
|
125
|
+
// ✅ GOOD: Use an object for 3+ parameters
|
|
126
|
+
interface CreateUserInput {
|
|
127
|
+
name: string;
|
|
128
|
+
email: string;
|
|
129
|
+
role?: UserRole;
|
|
130
|
+
isActive?: boolean;
|
|
131
|
+
avatar?: string;
|
|
132
|
+
bio?: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function createUser(input: CreateUserInput): User { ... }
|
|
136
|
+
|
|
137
|
+
// ❌ BAD: Boolean parameter (caller can't read intent)
|
|
138
|
+
setVisible(true);
|
|
139
|
+
|
|
140
|
+
// ✅ GOOD: Named method instead
|
|
141
|
+
show();
|
|
142
|
+
hide();
|
|
82
143
|
```
|
|
83
144
|
|
|
84
145
|
---
|
|
85
146
|
|
|
86
|
-
##
|
|
87
|
-
|
|
88
|
-
Errors are part of the contract. Don't hide them.
|
|
147
|
+
## SOLID Principles (With Code)
|
|
89
148
|
|
|
90
|
-
|
|
91
|
-
- Log full context: what operation failed, with what input, what the error was
|
|
92
|
-
- Never swallow errors silently (`catch (e) {}`)
|
|
93
|
-
- User-facing error messages are different from developer error messages — don't conflate them
|
|
149
|
+
### S — Single Responsibility
|
|
94
150
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
151
|
+
```typescript
|
|
152
|
+
// ❌ BAD: UserService does everything
|
|
153
|
+
class UserService {
|
|
154
|
+
createUser() { ... }
|
|
155
|
+
sendEmail() { ... }
|
|
156
|
+
generateReport() { ... }
|
|
157
|
+
uploadAvatar() { ... }
|
|
158
|
+
}
|
|
100
159
|
|
|
101
|
-
|
|
160
|
+
// ✅ GOOD: Separate concerns
|
|
161
|
+
class UserService { createUser() { ... } }
|
|
162
|
+
class EmailService { sendWelcomeEmail() { ... } }
|
|
163
|
+
class ReportService { generateUserReport() { ... } }
|
|
164
|
+
class AvatarService { upload() { ... } }
|
|
102
165
|
```
|
|
103
|
-
Arrange → set up what you need
|
|
104
|
-
Act → call the thing being tested
|
|
105
|
-
Assert → verify the outcome
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
**Test pyramid:**
|
|
109
|
-
- Unit tests: fast, isolated, abundant — test one function
|
|
110
|
-
- Integration tests: slower, test how components interact
|
|
111
|
-
- E2E tests: fewest, test the full user path
|
|
112
166
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
167
|
+
### O — Open/Closed
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
// ❌ BAD: Adding a new type requires modifying existing code
|
|
171
|
+
function calculateDiscount(type: string, amount: number): number {
|
|
172
|
+
if (type === "student") return amount * 0.20;
|
|
173
|
+
if (type === "veteran") return amount * 0.15;
|
|
174
|
+
if (type === "senior") return amount * 0.10; // must modify for every new type
|
|
175
|
+
return 0;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ✅ GOOD: Open for extension, closed for modification
|
|
179
|
+
interface DiscountStrategy {
|
|
180
|
+
calculate(amount: number): number;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
class StudentDiscount implements DiscountStrategy {
|
|
184
|
+
calculate(amount: number) { return amount * 0.20; }
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
class VeteranDiscount implements DiscountStrategy {
|
|
188
|
+
calculate(amount: number) { return amount * 0.15; }
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// New types = new class, no existing code changes
|
|
192
|
+
class EmployeeDiscount implements DiscountStrategy {
|
|
193
|
+
calculate(amount: number) { return amount * 0.25; }
|
|
194
|
+
}
|
|
195
|
+
```
|
|
123
196
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
197
|
+
### D — Dependency Inversion
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// ❌ BAD: High-level module depends on low-level concrete
|
|
201
|
+
class OrderService {
|
|
202
|
+
private db = new MySQLDatabase(); // coupled to MySQL
|
|
203
|
+
private mailer = new SendGridMailer(); // coupled to SendGrid
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// ✅ GOOD: Depend on abstractions (interfaces)
|
|
207
|
+
interface Database { save(data: unknown): Promise<void>; }
|
|
208
|
+
interface Mailer { send(to: string, body: string): Promise<void>; }
|
|
209
|
+
|
|
210
|
+
class OrderService {
|
|
211
|
+
constructor(
|
|
212
|
+
private db: Database, // can be MySQL, Postgres, in-memory
|
|
213
|
+
private mailer: Mailer, // can be SendGrid, SES, mock
|
|
214
|
+
) {}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
128
217
|
|
|
129
218
|
---
|
|
130
219
|
|
|
131
|
-
##
|
|
132
|
-
|
|
133
|
-
These are not optional:
|
|
220
|
+
## Error Handling
|
|
134
221
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
222
|
+
```typescript
|
|
223
|
+
// ❌ BAD: Swallowing errors
|
|
224
|
+
try {
|
|
225
|
+
await saveUser(user);
|
|
226
|
+
} catch (e) {
|
|
227
|
+
// silence
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ❌ BAD: Generic catch-all
|
|
231
|
+
try {
|
|
232
|
+
await processPayment(order);
|
|
233
|
+
} catch (e) {
|
|
234
|
+
console.log("Something went wrong");
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ✅ GOOD: Handle specific errors, propagate unexpected
|
|
238
|
+
try {
|
|
239
|
+
await processPayment(order);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
if (error instanceof InsufficientFundsError) {
|
|
242
|
+
return { success: false, message: "Insufficient funds" };
|
|
243
|
+
}
|
|
244
|
+
if (error instanceof PaymentGatewayError) {
|
|
245
|
+
logger.warn("Payment gateway unavailable, queuing for retry", { orderId: order.id });
|
|
246
|
+
await retryQueue.add(order);
|
|
247
|
+
return { success: false, message: "Payment processing delayed" };
|
|
248
|
+
}
|
|
249
|
+
throw error; // unexpected error — let it propagate
|
|
250
|
+
}
|
|
251
|
+
```
|
|
139
252
|
|
|
140
253
|
---
|
|
141
254
|
|
|
142
|
-
##
|
|
255
|
+
## Comments
|
|
143
256
|
|
|
144
|
-
|
|
257
|
+
```typescript
|
|
258
|
+
// ❌ BAD: Comments that restate the code
|
|
259
|
+
// Increment i by 1
|
|
260
|
+
i++;
|
|
145
261
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
* *✅ Clean Code:* `function add(a: number, b: number): number { return a + b; }`
|
|
149
|
-
2. **Defensive Programming Overkill:** Adding 15 `null` checks where the TypeScript compiler or the previous tier has already guaranteed validity.
|
|
150
|
-
3. **Premature Abstraction:** Creating an `AbstractDataManager` factory class with interfaces to parse a simple CSV file. Code what is needed *now*.
|
|
151
|
-
4. **Variable Diarrhea:** Extracting every step of a calculation into a separate `const` when a single readable line would suffice.
|
|
152
|
-
5. **Apologetic Comments:** `// TODO: Refactor this later` or `// I assumed this was the right way`. If you write it, own it. If it's incomplete, flag the user.
|
|
262
|
+
// Set the user's name
|
|
263
|
+
user.name = newName;
|
|
153
264
|
|
|
154
|
-
|
|
265
|
+
// Check if user is active
|
|
266
|
+
if (user.isActive) { ... }
|
|
155
267
|
|
|
156
|
-
|
|
268
|
+
// ✅ GOOD: Comments that explain WHY, not WHAT
|
|
269
|
+
// Tax exemption expires after 365 days per IRS Publication 334
|
|
270
|
+
const isExempt = daysSinceRegistration < 365;
|
|
157
271
|
|
|
158
|
-
|
|
272
|
+
// Using binary search here because the list is pre-sorted and
|
|
273
|
+
// can contain 100K+ items. Linear search caused P95 > 2s.
|
|
274
|
+
const index = binarySearch(sortedItems, target);
|
|
159
275
|
|
|
276
|
+
// Retry 3 times because the payment gateway has transient 503s
|
|
277
|
+
// during their daily maintenance window (02:00-02:15 UTC)
|
|
278
|
+
const result = await withRetry(() => chargeCard(amount), { maxRetries: 3 });
|
|
160
279
|
```
|
|
161
|
-
━━━ Clean Code Report ━━━━━━━━━━━━━━━━━━━━━━━━
|
|
162
|
-
Skill: Clean Code
|
|
163
|
-
Language: [detected language / framework]
|
|
164
|
-
Scope: [N files · N functions]
|
|
165
|
-
─────────────────────────────────────────────────
|
|
166
|
-
✅ Passed: [checks that passed, or "All clean"]
|
|
167
|
-
⚠️ Warnings: [non-blocking issues, or "None"]
|
|
168
|
-
❌ Blocked: [blocking issues requiring fix, or "None"]
|
|
169
|
-
─────────────────────────────────────────────────
|
|
170
|
-
VBC status: PENDING → VERIFIED
|
|
171
|
-
Evidence: [test output / lint pass / compile success]
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
**VBC (Verification-Before-Completion) is mandatory.**
|
|
175
|
-
Do not mark status as VERIFIED until concrete terminal evidence is provided.
|
|
176
|
-
|
|
177
280
|
|
|
178
281
|
---
|
|
179
282
|
|
|
180
|
-
##
|
|
181
|
-
|
|
182
|
-
**Slash command: `/generate`, `/review-types`**
|
|
183
|
-
**Active reviewers: `logic-reviewer` · `type-safety-reviewer`**
|
|
283
|
+
## Code Smells → Refactoring
|
|
184
284
|
|
|
185
|
-
### ❌ Forbidden AI Tropes in Code Generation
|
|
186
|
-
|
|
187
|
-
1. **Over-engineering:** Solving a problem with 3 classes when 1 function works perfectly.
|
|
188
|
-
2. **Commented-out code:** Submitting commented-out dead code, "just in case." Delete it.
|
|
189
|
-
3. **Implicit `any` types:** Failing to strictly type a critical parameter or return value.
|
|
190
|
-
|
|
191
|
-
### ✅ Pre-Flight Self-Audit
|
|
192
|
-
|
|
193
|
-
Review these questions before confirming code generation or review:
|
|
194
285
|
```
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
286
|
+
Smell → Refactoring
|
|
287
|
+
───────────────────────────────────────
|
|
288
|
+
Long function (>30 lines) → Extract method
|
|
289
|
+
Deep nesting (>3 levels) → Early return / guard clauses
|
|
290
|
+
Duplicate code → Extract shared function
|
|
291
|
+
Magic numbers → Named constants
|
|
292
|
+
Boolean parameters → Separate methods or options object
|
|
293
|
+
God class (>300 lines) → Split into focused classes
|
|
294
|
+
Feature envy → Move method to appropriate class
|
|
295
|
+
Primitive obsession → Value objects (Email, Money, UserId)
|
|
296
|
+
Long parameter list → Parameter object
|
|
200
297
|
```
|
|
201
298
|
|
|
202
|
-
|
|
299
|
+
```typescript
|
|
300
|
+
// Deep nesting → Early return
|
|
301
|
+
// ❌ BAD
|
|
302
|
+
function processUser(user: User) {
|
|
303
|
+
if (user) {
|
|
304
|
+
if (user.isActive) {
|
|
305
|
+
if (user.hasPermission("edit")) {
|
|
306
|
+
// actual logic buried 3 levels deep
|
|
307
|
+
doStuff();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ✅ GOOD: Guard clauses — fail fast, keep happy path unindented
|
|
314
|
+
function processUser(user: User) {
|
|
315
|
+
if (!user) return;
|
|
316
|
+
if (!user.isActive) return;
|
|
317
|
+
if (!user.hasPermission("edit")) return;
|
|
318
|
+
|
|
319
|
+
doStuff(); // happy path at top level
|
|
320
|
+
}
|
|
321
|
+
```
|
|
203
322
|
|
|
204
|
-
|
|
205
|
-
- ❌ **Forbidden:** Refactoring code or blindly applying "clean code" rules without verifying the code still compiles and works.
|
|
206
|
-
- ✅ **Required:** You are explicitly forbidden from finalizing a refactor without providing **concrete terminal evidence** (e.g., passing unit tests logs, successful linting execution, or type-check success) proving the refactored code maintains the original behavior.
|
|
323
|
+
---
|