codemaxxing 0.2.0 → 0.2.1

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.
@@ -477,6 +477,960 @@ export const REGISTRY: RegistrySkill[] = [
477
477
  - Don't hardcode config — use environment variables or config maps
478
478
  - Don't ignore failed CI — fix or revert immediately
479
479
  - Don't alert on everything — alert fatigue leads to ignored alerts
480
+ `,
481
+ },
482
+ {
483
+ name: "nextjs-app",
484
+ description: "Next.js App Router, Server/Client Components, server actions, caching, streaming",
485
+ version: "1.0.0",
486
+ author: "codemaxxing",
487
+ tags: ["nextjs", "react", "app-router", "server-components", "streaming"],
488
+ prompt: `# Next.js App Router Expert
489
+
490
+ ## Server Components vs Client Components
491
+ - Default to Server Components — they run on the server, ship zero JS to the client
492
+ - Add "use client" only when you need: useState, useEffect, event handlers, browser APIs
493
+ - Keep "use client" boundaries as low in the tree as possible — wrap only the interactive leaf
494
+ - Server Components can import Client Components, but NOT the reverse
495
+ - Pass server data to Client Components as serializable props — no functions, no classes
496
+ - Use composition: Server Component fetches data, passes it to a Client Component for interactivity
497
+
498
+ ## Route Handlers & Server Actions
499
+ - Use server actions ("use server") for mutations — forms, data writes, revalidation
500
+ - Prefer server actions over API route handlers for app-internal mutations
501
+ - Use route.ts (GET/POST/PUT/DELETE) for webhooks, external API consumers, and streaming responses
502
+ - Always validate input in server actions with Zod or similar — they're public endpoints
503
+ - Call revalidatePath() or revalidateTag() after mutations to bust the cache
504
+ - Use useActionState (React 19) for form state + pending UI, not manual useState
505
+
506
+ ## Routing & Layouts
507
+ - Use layout.tsx for shared UI that persists across navigations (navbars, sidebars)
508
+ - Use template.tsx instead of layout.tsx when you need fresh state on every navigation
509
+ - Implement loading.tsx per route segment for instant loading UI via Suspense
510
+ - Implement error.tsx per route segment — wraps in an ErrorBoundary automatically
511
+ - Use not-found.tsx for custom 404 pages, call notFound() to trigger programmatically
512
+ - Route groups (parentheses) for organizing without affecting URL: (marketing)/about/page.tsx
513
+ - Parallel routes (@modal) and intercepting routes ((..)photo) for modals and feeds
514
+
515
+ ## Data Fetching & Caching
516
+ - Fetch in Server Components directly — no useEffect, no client-side fetching for initial data
517
+ - Use the extended fetch options: \`fetch(url, { next: { revalidate: 3600, tags: ["posts"] } })\`
518
+ - unstable_cache or "use cache" directive for caching non-fetch operations (DB queries)
519
+ - Understand the cache layers: Request Memoization → Data Cache → Full Route Cache
520
+ - Use \`export const dynamic = "force-dynamic"\` to opt out of static rendering per route
521
+ - generateStaticParams for static generation of dynamic routes at build time
522
+
523
+ ## Streaming & Suspense
524
+ - Wrap slow data fetches in <Suspense> with a fallback to stream the page progressively
525
+ - Use loading.tsx for route-level Suspense — it wraps page.tsx automatically
526
+ - Multiple <Suspense> boundaries let fast content appear while slow content loads
527
+ - Streaming works out of the box — no special config needed with App Router
528
+
529
+ ## Metadata & SEO
530
+ - Export metadata object or generateMetadata function from page.tsx and layout.tsx
531
+ - Use generateMetadata for dynamic metadata (fetching title from DB)
532
+ - Metadata merges from layout → page, with page taking precedence
533
+ - Add opengraph-image.tsx and twitter-image.tsx for dynamic OG images
534
+ - Use sitemap.ts and robots.ts for programmatic SEO files
535
+
536
+ ## Middleware
537
+ - Use middleware.ts at the project root for auth checks, redirects, A/B testing, geo-routing
538
+ - Middleware runs on the Edge — keep it lightweight, no heavy computation or DB queries
539
+ - Use NextResponse.next() to continue, NextResponse.redirect() to redirect, NextResponse.rewrite() to rewrite
540
+ - Match routes with the config.matcher array — don't run middleware on static assets
541
+
542
+ ## Anti-Patterns
543
+ - Don't "use client" on layout.tsx — it defeats the purpose of Server Component layouts
544
+ - Don't fetch data on the client when you can fetch in a Server Component
545
+ - Don't use useEffect for data fetching in the App Router — use Server Components or server actions
546
+ - Don't mix Pages Router patterns (getServerSideProps) with App Router
547
+ - Don't put all components in a single "use client" boundary — isolate interactivity
548
+ - Don't forget to handle the loading and error states per route segment
549
+ `,
550
+ },
551
+ {
552
+ name: "tailwind-ui",
553
+ description: "Tailwind CSS, Shadcn UI, Radix primitives, responsive design, dark mode",
554
+ version: "1.0.0",
555
+ author: "codemaxxing",
556
+ tags: ["tailwind", "shadcn", "radix", "css", "ui", "design-system"],
557
+ prompt: `# Tailwind CSS & Shadcn UI Expert
558
+
559
+ ## Utility-First Patterns
560
+ - Build UI with utility classes directly — avoid creating CSS files unless truly necessary
561
+ - Group related utilities logically: layout → spacing → sizing → typography → colors → effects
562
+ - Use arbitrary values sparingly: \`w-[327px]\` is a sign you need a design token or a different approach
563
+ - Prefer Tailwind's spacing scale (p-4, m-6) over arbitrary values for consistency
564
+ - Use @apply only in base layer for truly repeated patterns (btn, input) — not for components
565
+ - Prefer component extraction (React/Svelte/Vue components) over @apply for reuse
566
+
567
+ ## Responsive Design
568
+ - Mobile-first: write base styles for mobile, override with sm:, md:, lg:, xl:, 2xl:
569
+ - Breakpoints: sm(640) md(768) lg(1024) xl(1280) 2xl(1536) — learn them
570
+ - Use container mx-auto for centered max-width layouts
571
+ - Responsive grids: \`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\`
572
+ - Hide/show elements responsively: \`hidden md:block\` or \`md:hidden\`
573
+ - Use responsive typography: \`text-sm md:text-base lg:text-lg\`
574
+
575
+ ## Dark Mode
576
+ - Use the "class" dark mode strategy for user-controlled toggling
577
+ - Apply dark variants: \`bg-white dark:bg-slate-900 text-slate-900 dark:text-slate-100\`
578
+ - Use CSS custom properties with Tailwind for theme-aware colors
579
+ - Define semantic color names in tailwind.config: primary, secondary, muted, accent
580
+ - Use Shadcn's built-in dark mode — it uses CSS variables under the hood
581
+ - Test both modes — don't forget hover/focus states in dark mode
582
+
583
+ ## Shadcn UI & Radix Primitives
584
+ - Install Shadcn components individually: \`npx shadcn@latest add button dialog\`
585
+ - Components live in your codebase (src/components/ui/) — customize them directly
586
+ - Use the cn() helper (clsx + tailwind-merge) for conditional + overridable classes
587
+ - cn() pattern: \`cn("base classes", conditional && "conditional-class", className)\`
588
+ - Radix provides unstyled accessible primitives — Shadcn adds Tailwind styles on top
589
+ - Always pass className through to the root element of custom components for composability
590
+
591
+ ## Component Composition
592
+ - Build complex components by composing Shadcn primitives: Dialog + Form + Button
593
+ - Use Radix's compound component pattern: \`<Select><SelectTrigger><SelectContent>...</SelectContent></SelectTrigger></Select>\`
594
+ - Use cva (class-variance-authority) for multi-variant components: size, color, state
595
+ - Pattern: \`const buttonVariants = cva("base", { variants: { size: { sm: "h-8", lg: "h-12" } } })\`
596
+ - Extend Shadcn components by wrapping them, not by modifying the generated code (easier upgrades)
597
+ - Use Slot from Radix (asChild prop) to merge props onto child elements
598
+
599
+ ## Accessibility
600
+ - Shadcn/Radix components handle ARIA attributes, keyboard navigation, and focus management
601
+ - Don't remove or override ARIA roles/attributes added by Radix primitives
602
+ - Use sr-only class for screen-reader-only text
603
+ - Ensure sufficient color contrast — Tailwind's default palette mostly passes WCAG AA
604
+ - Test with keyboard navigation: Tab, Enter, Escape, Arrow keys should all work
605
+
606
+ ## Anti-Patterns
607
+ - Don't fight Tailwind by writing custom CSS for things utilities already handle
608
+ - Don't create deeply nested className strings — extract components instead
609
+ - Don't use inline styles alongside Tailwind — pick one approach
610
+ - Don't ignore the cn() helper — raw string concatenation breaks with conflicting utilities
611
+ - Don't copy-paste Shadcn components without understanding the underlying Radix primitives
612
+ - Don't use arbitrary values for spacing when a Tailwind scale value is close enough
613
+ - Don't forget to import Tailwind's base/components/utilities layers in your CSS entry point
614
+ `,
615
+ },
616
+ {
617
+ name: "svelte-kit",
618
+ description: "Svelte 5 runes, SvelteKit routing, load functions, form actions, SSR/SSG",
619
+ version: "1.0.0",
620
+ author: "codemaxxing",
621
+ tags: ["svelte", "sveltekit", "runes", "ssr", "frontend"],
622
+ prompt: `# Svelte 5 & SvelteKit Expert
623
+
624
+ ## Svelte 5 Runes
625
+ - Use $state() for reactive state: \`let count = $state(0)\` — replaces the old \`let count = 0\` reactivity
626
+ - Use $derived() for computed values: \`let doubled = $derived(count * 2)\` — replaces $: reactive labels
627
+ - Use $derived.by() for multi-line derivations: \`let total = $derived.by(() => { /* compute */ return val })\`
628
+ - Use $effect() for side effects: replaces onMount + $: reactive statements that cause side effects
629
+ - $effect runs after DOM update — use $effect.pre() if you need to run before DOM update
630
+ - Use $props() to declare component props: \`let { name, age = 25 }: Props = $props()\`
631
+ - Use $bindable() for two-way bindable props: \`let { value = $bindable() }: Props = $props()\`
632
+ - $inspect() for debugging reactive values — like console.log but re-runs when values change
633
+
634
+ ## Component Patterns
635
+ - Svelte components are .svelte files with <script>, markup, and <style> sections
636
+ - Use {#snippet name(params)} for reusable markup blocks within a component (replaces slots)
637
+ - Use {@render snippetName(args)} to render snippets
638
+ - Children content is received as a children snippet: \`let { children }: Props = $props()\` then {@render children?.()}
639
+ - Use \`<svelte:component this={Component}\` for dynamic components
640
+ - Scoped styles by default — styles in <style> only affect the current component
641
+ - Use :global() sparingly for styles that must escape component scope
642
+
643
+ ## SvelteKit Routing
644
+ - File-based routing: src/routes/about/+page.svelte → /about
645
+ - Dynamic params: src/routes/users/[id]/+page.svelte → /users/123
646
+ - Layout nesting: +layout.svelte wraps all child routes automatically
647
+ - Use +page.ts for universal load (runs server + client), +page.server.ts for server-only load
648
+ - Use +error.svelte for error pages, +layout.server.ts for layout-level data loading
649
+ - Group routes without URL impact: (group)/route/+page.svelte
650
+ - Rest params: [...slug]/+page.svelte catches all remaining path segments
651
+
652
+ ## Load Functions
653
+ - Load functions in +page.ts export a load function that returns data as props
654
+ - Access params, url, fetch (SvelteKit's enhanced fetch with credentials), and parent data
655
+ - Use depends() to declare custom invalidation keys: \`depends('app:posts')\`
656
+ - Call invalidate('app:posts') or invalidateAll() to re-run load functions
657
+ - Server load functions (+page.server.ts) can access DB, env vars, and secrets directly
658
+ - Data flows: +layout.server.ts → +layout.ts → +page.server.ts → +page.ts → component
659
+
660
+ ## Form Actions
661
+ - Define actions in +page.server.ts: \`export const actions = { default: async ({ request }) => { ... } }\`
662
+ - Use <form method="POST"> — SvelteKit handles it without JS (progressive enhancement)
663
+ - Named actions: \`<form method="POST" action="?/create">\` maps to \`actions: { create: async () => {} }\`
664
+ - Use enhance action for progressive enhancement: \`<form method="POST" use:enhance>\`
665
+ - Return validation errors with fail(): \`return fail(400, { email, error: "Invalid email" })\`
666
+ - Access returned data in the page via $page.form or the form prop from load
667
+
668
+ ## SSR, SSG & Prerendering
669
+ - SSR is on by default — pages render on the server, then hydrate on the client
670
+ - Prerender static pages: \`export const prerender = true\` in +page.ts or +layout.ts
671
+ - Use adapter-static for full SSG (all pages prerendered)
672
+ - Disable SSR for SPA pages: \`export const ssr = false\` — use only when necessary
673
+ - Use adapter-node for Node server, adapter-vercel/adapter-netlify for serverless
674
+
675
+ ## Anti-Patterns
676
+ - Don't use $: reactive labels in Svelte 5 — migrate to $state, $derived, $effect
677
+ - Don't mutate $state values indirectly without assignment — Svelte 5 uses proxies but keep mutations explicit
678
+ - Don't use $effect for derived values — use $derived instead
679
+ - Don't put secrets or DB calls in +page.ts (universal) — use +page.server.ts for server-only code
680
+ - Don't forget use:enhance on forms — without it, you lose SvelteKit's progressive enhancement
681
+ - Don't create stores for local component state — $state() rune handles it
682
+ `,
683
+ },
684
+ {
685
+ name: "react-native",
686
+ description: "Expo, React Navigation, platform-specific code, performance, EAS builds",
687
+ version: "1.0.0",
688
+ author: "codemaxxing",
689
+ tags: ["react-native", "expo", "mobile", "ios", "android", "navigation"],
690
+ prompt: `# React Native & Expo Expert
691
+
692
+ ## Expo Workflow
693
+ - Start with Expo for new projects — it handles native config, builds, and OTA updates
694
+ - Use Expo Router for file-based routing (built on React Navigation)
695
+ - Use expo-dev-client for custom native modules during development
696
+ - Use EAS Build for cloud builds: \`eas build --platform ios\` — no local Xcode/Android Studio needed
697
+ - Use EAS Submit to automate App Store and Play Store submissions
698
+ - Use EAS Update for OTA JavaScript updates — skip the app store review cycle
699
+ - Config plugins (app.config.ts) let you modify native projects without ejecting
700
+ - Use expo-constants, expo-device, expo-file-system for cross-platform native APIs
701
+
702
+ ## Navigation (React Navigation / Expo Router)
703
+ - Use Expo Router: app/_layout.tsx defines the navigator, app/index.tsx is the home screen
704
+ - Stack navigator for hierarchical flows (push/pop), Tab navigator for main app sections
705
+ - Use typed routes: \`router.push("/users/[id]", { id: "123" })\`
706
+ - Deep linking works automatically with Expo Router — configure in app.config
707
+ - Use navigation state to persist and restore navigation across app restarts
708
+ - Modals: use presentation: "modal" in stack screen options
709
+ - Avoid deeply nested navigators — flatten where possible for performance
710
+
711
+ ## Layout & Styling
712
+ - Always wrap content in SafeAreaView (expo-safe-area-context) to avoid notches/status bars
713
+ - Use StyleSheet.create() for styles — it validates and optimizes at creation time
714
+ - Flexbox is the default layout system — flexDirection defaults to "column" (not "row" like web)
715
+ - Use Dimensions or useWindowDimensions() for responsive layouts
716
+ - Platform-specific code: Platform.select({ ios: value, android: value }) or .ios.tsx / .android.tsx files
717
+ - Use react-native-reanimated for 60fps animations on the native thread
718
+ - Avoid inline styles in render — they create new objects on every render
719
+
720
+ ## State Management
721
+ - Use Zustand for global state — lightweight, works great with React Native
722
+ - Use MMKV (react-native-mmkv) for persistent storage — 30x faster than AsyncStorage
723
+ - Use TanStack Query for server state — caching, refetching, offline support
724
+ - For offline-first: combine TanStack Query + MMKV persister + network-aware sync
725
+ - Keep navigation state separate from app state — React Navigation manages its own state
726
+
727
+ ## Performance
728
+ - Use FlatList (not ScrollView) for lists — it virtualizes, rendering only visible items
729
+ - FlatList: set keyExtractor, getItemLayout (fixed height), maxToRenderPerBatch, windowSize
730
+ - Use React.memo for list items to prevent re-renders when data hasn't changed
731
+ - Use useCallback for event handlers passed to list items
732
+ - Avoid passing new objects/arrays as props in render — memoize or define outside
733
+ - Use Hermes engine (default in Expo) — it improves startup time and memory usage
734
+ - Profile with React DevTools and Flipper — never optimize without measuring first
735
+
736
+ ## Native Modules & Platform Code
737
+ - Check expo packages first before reaching for community native modules
738
+ - Use expo-modules-api to write custom native modules in Swift/Kotlin
739
+ - Bridge native UI with requireNativeComponent or Expo's native view pattern
740
+ - Handle platform differences explicitly — don't assume iOS behavior works on Android
741
+ - Test on real devices — simulators miss performance issues, permissions, and hardware quirks
742
+
743
+ ## Anti-Patterns
744
+ - Don't use ScrollView for long lists — use FlatList or FlashList
745
+ - Don't use web-specific APIs (window, document, localStorage) — they don't exist
746
+ - Don't ignore the keyboard — use KeyboardAvoidingView or react-native-keyboard-aware-scroll-view
747
+ - Don't hardcode dimensions — use relative sizing (flex) and useWindowDimensions
748
+ - Don't skip testing on Android — platform differences are real and frequent
749
+ - Don't use Animated API for complex animations — use react-native-reanimated instead
750
+ `,
751
+ },
752
+ {
753
+ name: "swift-ios",
754
+ description: "SwiftUI, async/await, Combine, SwiftData, MVVM, App Store guidelines",
755
+ version: "1.0.0",
756
+ author: "codemaxxing",
757
+ tags: ["swift", "ios", "swiftui", "apple", "mobile", "xcode"],
758
+ prompt: `# Swift iOS Development Expert
759
+
760
+ ## SwiftUI Views
761
+ - Build UIs declaratively with structs conforming to View — return a body computed property
762
+ - Use VStack, HStack, ZStack for layout composition — avoid GeometryReader unless truly needed
763
+ - Prefer LazyVStack/LazyHStack inside ScrollView for long lists — they load items on demand
764
+ - Use List for built-in swipe actions, selection, and pull-to-refresh
765
+ - Modifiers order matters: \`.padding().background().cornerRadius()\` differs from reordering
766
+ - Extract subviews into separate structs to keep body readable (under ~30 lines)
767
+ - Use @ViewBuilder for functions that return opaque view types conditionally
768
+
769
+ ## Property Wrappers
770
+ - @State for local view state — value types owned by the view
771
+ - @Binding for two-way connection to a parent's @State
772
+ - @StateObject for creating ObservableObject instances (create once, view owns it)
773
+ - @ObservedObject for ObservableObject passed in from parent (view doesn't own it)
774
+ - @EnvironmentObject for dependency injection of ObservableObject through the view hierarchy
775
+ - @Environment(\\.colorScheme) for reading system environment values
776
+ - @AppStorage for UserDefaults-backed persistent state
777
+ - In iOS 17+: use @Observable macro instead of ObservableObject for simpler observation
778
+
779
+ ## MVVM Architecture
780
+ - View: SwiftUI views — declarative UI, no business logic
781
+ - ViewModel: @Observable class that holds state and business logic, exposes computed properties
782
+ - Model: plain structs/classes for data — Codable for serialization
783
+ - ViewModels should not import SwiftUI — keep them testable with plain Swift
784
+ - Use protocols for dependencies (networking, storage) to enable testability
785
+ - One ViewModel per screen/feature — avoid god ViewModels
786
+
787
+ ## Async/Await & Concurrency
788
+ - Use async/await for network calls, file I/O, and any asynchronous work
789
+ - Use Task { } in SwiftUI to launch async work from synchronous contexts (onAppear, buttons)
790
+ - Use TaskGroup for concurrent parallel operations with structured cancellation
791
+ - Actor types protect mutable state from data races — use for shared resources
792
+ - @MainActor ensures code runs on the main thread — use for UI-updating classes
793
+ - Use AsyncSequence and for-await loops for streaming data (WebSockets, file reading)
794
+ - Handle cancellation: check Task.isCancelled or use withTaskCancellationHandler
795
+
796
+ ## Data Persistence
797
+ - SwiftData (iOS 17+): use @Model macro on classes, @Query in views for reactive fetches
798
+ - SwiftData replaces Core Data for most use cases — simpler API, better SwiftUI integration
799
+ - Use ModelContainer for configuration, ModelContext for CRUD operations
800
+ - For key-value storage: UserDefaults (@AppStorage) for small data, Keychain for secrets
801
+ - For complex legacy needs: Core Data with NSPersistentContainer and @FetchRequest
802
+
803
+ ## App Store Guidelines
804
+ - Follow Human Interface Guidelines — use standard navigation patterns and system controls
805
+ - Request permissions just-in-time with clear usage descriptions in Info.plist
806
+ - Implement in-app purchases with StoreKit 2 — server-side validation for subscriptions
807
+ - Support Dynamic Type for text accessibility — use system fonts and relative sizing
808
+ - Add VoiceOver labels to all interactive elements: \`.accessibilityLabel("Close button")\`
809
+ - Test on multiple device sizes and orientations — use preview providers
810
+
811
+ ## Anti-Patterns
812
+ - Don't use force unwraps (!) in production code — use guard let, if let, or ?? defaults
813
+ - Don't put networking or heavy logic in View bodies — use ViewModels
814
+ - Don't use GeometryReader for simple layouts — it causes unnecessary complexity
815
+ - Don't ignore memory management — watch for retain cycles with [weak self] in closures
816
+ - Don't use Timer for background work — use Task with proper lifecycle management
817
+ - Don't hardcode strings — use String Catalogs or NSLocalizedString for localization
818
+ `,
819
+ },
820
+ {
821
+ name: "flutter",
822
+ description: "Dart patterns, widget tree, state management (Riverpod/Bloc), Material Design 3",
823
+ version: "1.0.0",
824
+ author: "codemaxxing",
825
+ tags: ["flutter", "dart", "mobile", "widgets", "riverpod", "material"],
826
+ prompt: `# Flutter & Dart Expert
827
+
828
+ ## Dart Patterns
829
+ - Use null safety: \`String?\` for nullable, \`!\` only when you're certain (prefer null checks)
830
+ - Prefer final for variables that won't be reassigned: \`final name = "Flutter";\`
831
+ - Use named parameters with required keyword: \`void greet({required String name})\`
832
+ - Use extension methods to add functionality to existing types without subclassing
833
+ - Use sealed classes (Dart 3) for exhaustive pattern matching on state variants
834
+ - Cascade notation (..) for chaining operations on the same object
835
+ - Use records for lightweight data grouping: \`(String, int) getNameAndAge()\`
836
+ - Pattern matching with switch expressions: \`final label = switch(status) { Status.ok => "Good" };\`
837
+
838
+ ## Widget Tree & Composition
839
+ - Everything is a widget — compose small, focused widgets into complex UIs
840
+ - StatelessWidget for UI that depends only on constructor parameters (immutable)
841
+ - StatefulWidget when the widget needs to manage mutable state with setState()
842
+ - Keep build() methods lean — extract sub-widget methods into separate widget classes
843
+ - Use const constructors wherever possible — they enable widget tree optimizations
844
+ - Prefer composition over inheritance — wrap widgets rather than extending them
845
+ - Use the Builder pattern for context-dependent widgets: \`Builder(builder: (context) => ...)\`
846
+
847
+ ## State Management
848
+ - setState() for local widget state — fine for simple, isolated state
849
+ - Riverpod (recommended): Provider, StateNotifier, AsyncNotifier for scalable state
850
+ - Riverpod patterns: define providers at top level, use ref.watch() in widgets, ref.read() for actions
851
+ - Use AsyncValue (Riverpod) for loading/error/data states from async operations
852
+ - Bloc pattern: Events → Bloc → States — good for complex business logic with clear event flows
853
+ - Use ChangeNotifier + Provider for simpler apps, but Riverpod scales better
854
+ - Avoid global mutable state — use providers/blocs to scope state to features
855
+
856
+ ## Navigation & Routing
857
+ - Use GoRouter for declarative, URL-based routing with deep link support
858
+ - Define routes in a central configuration: \`GoRouter(routes: [GoRoute(path: "/", builder: ...)])\`
859
+ - Use shell routes for persistent navigation (bottom tabs, drawers)
860
+ - Pass parameters via path or query params — avoid passing complex objects through navigation
861
+ - Use guards (redirect) for authentication-protected routes
862
+
863
+ ## Platform Channels & Integration
864
+ - Use MethodChannel for calling native platform code (Swift/Kotlin) from Dart
865
+ - Use EventChannel for streaming data from native to Dart (sensors, Bluetooth)
866
+ - Use Pigeon for type-safe platform channel communication — generates boilerplate
867
+ - Check platform with \`Platform.isIOS\` / \`Platform.isAndroid\` for platform-specific behavior
868
+ - Use federated plugins to share platform-specific implementations across packages
869
+
870
+ ## Material Design 3 & Theming
871
+ - Use Material 3: \`MaterialApp(theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.blue))\`
872
+ - Use ColorScheme for systematic color usage: primary, secondary, surface, error variants
873
+ - Use Theme.of(context) to access theme data — never hardcode colors or text styles
874
+ - Use TextTheme for consistent typography: \`Theme.of(context).textTheme.headlineMedium\`
875
+ - Support dark mode: provide both light and dark ThemeData to MaterialApp
876
+ - Use adaptive widgets (e.g., Switch.adaptive) for platform-appropriate appearance
877
+
878
+ ## Performance
879
+ - Use const widgets to avoid unnecessary rebuilds — the framework skips const subtrees
880
+ - Use ListView.builder for long lists — it creates items lazily as they scroll into view
881
+ - Profile with Flutter DevTools: widget rebuild counts, frame rendering times, memory
882
+ - Use RepaintBoundary to isolate frequently updating parts of the widget tree
883
+ - Avoid building widgets in initState — use didChangeDependencies for context-dependent setup
884
+ - Use Isolates for CPU-heavy work — they run in separate threads without blocking UI
885
+
886
+ ## Anti-Patterns
887
+ - Don't put all logic in widgets — separate business logic into repositories/services
888
+ - Don't use setState for state shared across widgets — use a state management solution
889
+ - Don't create deep widget nesting (10+ levels) — extract into named widget classes
890
+ - Don't ignore keys in lists — use ValueKey or ObjectKey for items that move/reorder
891
+ - Don't use BuildContext across async gaps — capture what you need before the await
892
+ - Don't hardcode sizes — use MediaQuery, LayoutBuilder, or Flex for responsive layouts
893
+ `,
894
+ },
895
+ {
896
+ name: "rust-systems",
897
+ description: "Ownership, borrowing, error handling, async Tokio, Actix/Axum, unsafe guidelines",
898
+ version: "1.0.0",
899
+ author: "codemaxxing",
900
+ tags: ["rust", "systems", "tokio", "axum", "ownership", "concurrency"],
901
+ prompt: `# Rust Systems Programming Expert
902
+
903
+ ## Ownership & Borrowing
904
+ - Each value has exactly one owner — when the owner goes out of scope, the value is dropped
905
+ - Use references (&T) for read-only borrowing, (&mut T) for mutable borrowing
906
+ - Rule: unlimited &T OR exactly one &mut T — never both simultaneously
907
+ - Clone explicitly when you need a separate owned copy — don't fight the borrow checker blindly
908
+ - Use Cow<str> (Clone on Write) when you sometimes need to own, sometimes just borrow
909
+ - Prefer &str over String in function parameters — accepts both String and &str
910
+ - Use .as_ref(), .as_str(), .into() for ergonomic type conversions
911
+
912
+ ## Error Handling
913
+ - Use Result<T, E> for recoverable errors — never panic in library code
914
+ - Use the ? operator to propagate errors up the call chain concisely
915
+ - Define custom error enums with thiserror: \`#[error("not found: {id}")] NotFound { id: u64 }\`
916
+ - Use anyhow::Result for application code where you don't need typed errors
917
+ - Reserve panic!() and .unwrap() for truly unrecoverable situations or tests
918
+ - Use .expect("reason") over .unwrap() — document WHY you believe it won't fail
919
+ - Map errors at boundaries: \`.map_err(|e| MyError::Database(e))?\`
920
+
921
+ ## Lifetimes
922
+ - Lifetimes prevent dangling references — the compiler ensures references outlive their use
923
+ - Elision rules handle most cases — only annotate when the compiler asks you to
924
+ - Named lifetimes: \`fn first<'a>(items: &'a [T]) -> &'a T\` — output lives as long as input
925
+ - 'static means the reference lives for the entire program — owned data or compile-time constants
926
+ - Lifetime bounds on structs: \`struct Parser<'a> { input: &'a str }\` — struct can't outlive the reference
927
+ - When fighting lifetimes: consider if you should own the data instead of borrowing
928
+
929
+ ## Async with Tokio
930
+ - Use #[tokio::main] for the async runtime entry point
931
+ - Use tokio::spawn for concurrent tasks — returns a JoinHandle for awaiting results
932
+ - Use tokio::select! to race multiple futures — first one to complete wins
933
+ - Use tokio::sync::Mutex for async-safe locking (not std::sync::Mutex in async code)
934
+ - Use channels (mpsc, broadcast, oneshot) for communication between tasks
935
+ - Use tokio::time::timeout to prevent indefinite waits on futures
936
+ - Use Stream (futures/tokio-stream) for async iterators — process items as they arrive
937
+
938
+ ## Web with Axum
939
+ - Define handlers as async functions: \`async fn get_user(Path(id): Path<u64>) -> impl IntoResponse\`
940
+ - Use extractors for parsing: Path, Query, Json, State, Headers — composable and type-safe
941
+ - Shared state with State(Arc<AppState>) — wrap in Arc for thread-safe sharing
942
+ - Use tower middleware for logging, CORS, auth, rate limiting — composable layers
943
+ - Error handling: implement IntoResponse for your error type to control HTTP responses
944
+ - Use Router::new().route("/users", get(list).post(create)) for clean route definitions
945
+ - Use axum::serve with graceful_shutdown for production deployments
946
+
947
+ ## Cargo & Project Structure
948
+ - Use Cargo workspaces for multi-crate projects: shared deps, unified builds
949
+ - Feature flags for conditional compilation: \`#[cfg(feature = "postgres")]\`
950
+ - Use clippy: \`cargo clippy -- -W clippy::all\` — it catches common mistakes and idioms
951
+ - Organize: lib.rs for library logic, main.rs for binary entry, mod.rs for module roots
952
+ - Use integration tests in tests/ directory — they test your public API as an external consumer
953
+ - Profile with cargo bench (criterion) and cargo flamegraph for performance optimization
954
+
955
+ ## Unsafe Guidelines
956
+ - Avoid unsafe unless absolutely necessary — most Rust code should be 100% safe
957
+ - Valid reasons for unsafe: FFI, raw pointer manipulation, implementing unsafe traits
958
+ - Document every unsafe block with a SAFETY comment explaining why it's sound
959
+ - Minimize the scope of unsafe blocks — keep the unsafe surface area as small as possible
960
+ - Use safe abstractions around unsafe internals — expose a safe API to callers
961
+ - Prefer well-audited crates (libc, nix, windows-rs) over raw FFI bindings
962
+
963
+ ## Anti-Patterns
964
+ - Don't clone everything to avoid the borrow checker — understand ownership first
965
+ - Don't use Rc/RefCell as a default — they add runtime overhead, use references instead
966
+ - Don't ignore compiler warnings — Rust warnings almost always indicate real issues
967
+ - Don't use String when &str suffices — unnecessary allocation
968
+ - Don't block the async runtime with synchronous I/O — use tokio::task::spawn_blocking
969
+ - Don't write unsafe for convenience — only for correctness when safe Rust can't express it
970
+ `,
971
+ },
972
+ {
973
+ name: "go-backend",
974
+ description: "Go standard library, error handling, goroutines, interfaces, table-driven tests",
975
+ version: "1.0.0",
976
+ author: "codemaxxing",
977
+ tags: ["go", "golang", "backend", "concurrency", "testing"],
978
+ prompt: `# Go Backend Expert
979
+
980
+ ## Standard Library First
981
+ - Use net/http for HTTP servers — it's production-ready and widely understood
982
+ - Use http.ServeMux (Go 1.22+) with method-aware routing: \`mux.HandleFunc("GET /users/{id}", handler)\`
983
+ - Use encoding/json for JSON: \`json.NewDecoder(r.Body).Decode(&v)\` for requests, json.NewEncoder for responses
984
+ - Use database/sql with a driver (pgx, go-sql-driver) — it handles connection pooling
985
+ - Use log/slog (Go 1.21+) for structured logging: \`slog.Info("user created", "id", user.ID)\`
986
+ - Use html/template for server-rendered HTML — auto-escapes to prevent XSS
987
+ - Use embed for bundling static assets and templates into the binary
988
+ - Reach for third-party libraries only when the stdlib genuinely falls short
989
+
990
+ ## Error Handling
991
+ - Errors are values — return them, don't panic: \`func Open(name string) (*File, error)\`
992
+ - Always check errors: \`if err != nil { return fmt.Errorf("opening config: %w", err) }\`
993
+ - Wrap errors with %w for context: \`fmt.Errorf("creating user %s: %w", name, err)\`
994
+ - Use errors.Is() to check for specific errors: \`if errors.Is(err, sql.ErrNoRows)\`
995
+ - Use errors.As() to extract typed errors: \`var pathErr *os.PathError; errors.As(err, &pathErr)\`
996
+ - Define sentinel errors: \`var ErrNotFound = errors.New("not found")\`
997
+ - Don't use panic for expected failures — reserve panic for truly unrecoverable programmer errors
998
+
999
+ ## Goroutines & Channels
1000
+ - Use goroutines for concurrent work — they're lightweight (2KB stack) and managed by the runtime
1001
+ - Always ensure goroutines can terminate — use context.Context for cancellation
1002
+ - Use sync.WaitGroup to wait for a group of goroutines to finish
1003
+ - Use channels for communication between goroutines: \`ch := make(chan Result, bufSize)\`
1004
+ - Buffered channels for producer/consumer, unbuffered for synchronization
1005
+ - Use select for multiplexing: waiting on multiple channels or timeouts
1006
+ - Use errgroup (golang.org/x/sync) for groups of goroutines that return errors
1007
+ - Avoid goroutine leaks: always close channels, cancel contexts, and handle done signals
1008
+
1009
+ ## Interfaces
1010
+ - Interfaces are small: \`type Reader interface { Read(p []byte) (n int, err error) }\`
1011
+ - Accept interfaces, return structs — keep interfaces at the consumer, not the producer
1012
+ - Don't create interfaces until you need them — premature abstraction is costly in Go
1013
+ - Implicit implementation: types satisfy interfaces without explicit declaration
1014
+ - Use io.Reader, io.Writer, fmt.Stringer — standard interfaces enable composition
1015
+ - Empty interface (any) should be rare — use generics (Go 1.18+) for type-safe polymorphism
1016
+
1017
+ ## Project Structure
1018
+ - Keep it simple: cmd/ for entry points, internal/ for private packages, pkg/ only if truly reusable
1019
+ - Use internal/ to prevent external packages from importing your implementation details
1020
+ - One package per directory — package name matches the directory name
1021
+ - Avoid circular dependencies — they're compile errors in Go
1022
+ - Use Go modules: go.mod at the root, run go mod tidy to clean up dependencies
1023
+ - Follow standard naming: lowercase packages, MixedCaps for exported, camelCase for unexported
1024
+
1025
+ ## Table-Driven Tests
1026
+ - Use table-driven tests for exhaustive input/output coverage:
1027
+ - Pattern: define []struct{ name, input, want }, loop with t.Run(tc.name, func(t *testing.T) { ... })
1028
+ - Use t.Parallel() for independent tests — speeds up test suites
1029
+ - Use testify/assert for readable assertions, or stick with stdlib for zero dependencies
1030
+ - Use t.Helper() in test helper functions to fix file/line reporting
1031
+ - Use t.Cleanup() for teardown — it runs after the test and all its subtests
1032
+ - Use testcontainers-go for integration tests with real databases and services
1033
+
1034
+ ## Anti-Patterns
1035
+ - Don't ignore errors with \`_ = someFunc()\` — handle or explicitly document why it's safe
1036
+ - Don't use init() functions — they make testing hard and hide initialization order
1037
+ - Don't use global mutable state — pass dependencies explicitly via struct fields or function params
1038
+ - Don't overuse channels — a mutex is simpler when you just need to protect shared data
1039
+ - Don't create interfaces for single implementations — that's Java, not Go
1040
+ - Don't return interfaces — return concrete types and let consumers define their own interfaces
1041
+ `,
1042
+ },
1043
+ {
1044
+ name: "node-backend",
1045
+ description: "Express/Fastify, middleware, input validation, JWT auth, error handling, graceful shutdown",
1046
+ version: "1.0.0",
1047
+ author: "codemaxxing",
1048
+ tags: ["node", "express", "fastify", "backend", "api", "middleware"],
1049
+ prompt: `# Node.js Backend Expert
1050
+
1051
+ ## Framework Choice
1052
+ - Express for simplicity and ecosystem maturity — huge middleware library, well-documented
1053
+ - Fastify for performance — 2-3x faster than Express, built-in schema validation, TypeScript-first
1054
+ - Use Fastify's plugin system for encapsulated, reusable modules
1055
+ - Both support async handlers — always use async/await, never callbacks
1056
+ - For new projects: Fastify is recommended for its speed, schema validation, and TypeScript support
1057
+
1058
+ ## Middleware Patterns
1059
+ - Middleware executes in order — put auth before route handlers, error handlers last
1060
+ - Express: \`app.use(middleware)\` for global, \`router.use(middleware)\` for scoped
1061
+ - Fastify: use hooks (onRequest, preHandler, onSend) or plugins for middleware-like behavior
1062
+ - Common middleware stack: cors → helmet → rate-limiter → body-parser → auth → routes → error-handler
1063
+ - Keep middleware focused: one concern per middleware (logging, auth, validation)
1064
+ - Use express-async-errors or wrap handlers to catch async errors automatically
1065
+
1066
+ ## Input Validation
1067
+ - Validate ALL incoming data at the boundary — never trust req.body, req.params, req.query
1068
+ - Use Zod for runtime validation + TypeScript type inference: \`const UserSchema = z.object({...})\`
1069
+ - Validate in middleware: parse input before it reaches the handler, reject invalid requests early
1070
+ - Pattern: \`const data = UserSchema.parse(req.body)\` — throws ZodError on invalid input
1071
+ - Fastify: use JSON Schema in route definitions for automatic validation + serialization
1072
+ - Validate path params and query strings too — not just the body
1073
+ - Return structured validation errors: \`{ errors: [{ field: "email", message: "Invalid email" }] }\`
1074
+
1075
+ ## Authentication
1076
+ - Use bcrypt (cost factor 12+) for password hashing — never store plaintext passwords
1077
+ - JWTs for stateless auth: short-lived access tokens (15min), longer refresh tokens (7 days)
1078
+ - Store refresh tokens in httpOnly cookies — never in localStorage (XSS vulnerability)
1079
+ - Verify JWTs with jose or jsonwebtoken: check signature, expiry, issuer, audience
1080
+ - Middleware pattern: decode JWT → find user → attach to req.user → call next()
1081
+ - Use passport.js only if you need multiple OAuth providers — otherwise it's overhead
1082
+ - Implement token rotation: issue new refresh token on each use, revoke old one
1083
+
1084
+ ## Error Handling
1085
+ - Use a centralized error handler middleware — the last app.use() with (err, req, res, next)
1086
+ - Define custom error classes: AppError extends Error with statusCode and isOperational
1087
+ - Distinguish operational errors (bad input, not found) from programmer errors (null reference)
1088
+ - Never send stack traces to clients in production — log them, return a generic message
1089
+ - Use process.on('unhandledRejection') and process.on('uncaughtException') as safety nets
1090
+ - Return consistent error format: \`{ error: { code: "NOT_FOUND", message: "User not found" } }\`
1091
+
1092
+ ## Rate Limiting & Security
1093
+ - Use express-rate-limit or @fastify/rate-limit — essential for public APIs
1094
+ - Apply stricter limits to auth endpoints (login, register, password reset)
1095
+ - Use helmet for security headers: CSP, HSTS, X-Frame-Options, X-Content-Type-Options
1096
+ - Use cors with explicit origin allowlist — never use \`origin: "*"\` in production
1097
+ - Implement request ID (uuid) for tracing requests across services and logs
1098
+
1099
+ ## Structured Logging & Graceful Shutdown
1100
+ - Use pino (Fastify default) or winston — never console.log in production
1101
+ - Log as JSON with consistent fields: timestamp, level, requestId, message, metadata
1102
+ - Log at boundaries: incoming request, outgoing response, external API calls, errors
1103
+ - Graceful shutdown: handle SIGTERM/SIGINT → stop accepting requests → finish in-flight → close DB/Redis → exit
1104
+ - Pattern: \`process.on("SIGTERM", async () => { await server.close(); await db.end(); process.exit(0); })\`
1105
+ - Set a shutdown timeout (10-30s) — force exit if graceful shutdown hangs
1106
+
1107
+ ## Anti-Patterns
1108
+ - Don't use callback-based APIs — use promisify() or native promise alternatives
1109
+ - Don't block the event loop with synchronous operations (fs.readFileSync, crypto.pbkdf2Sync)
1110
+ - Don't catch errors silently: \`catch (e) {}\` — always log or handle meaningfully
1111
+ - Don't use \`res.send()\` after \`next()\` — it causes "headers already sent" errors
1112
+ - Don't store sessions in memory — use Redis or a database for production session storage
1113
+ - Don't skip input validation because "the frontend validates" — the frontend is untrusted
1114
+ `,
1115
+ },
1116
+ {
1117
+ name: "sql-master",
1118
+ description: "Query optimization, indexing, schema design, migrations, CTEs, window functions",
1119
+ version: "1.0.0",
1120
+ author: "codemaxxing",
1121
+ tags: ["sql", "postgres", "mysql", "database", "indexing", "performance"],
1122
+ prompt: `# SQL Mastery Expert
1123
+
1124
+ ## Schema Design
1125
+ - Use appropriate data types: INTEGER for IDs, TEXT/VARCHAR for strings, TIMESTAMPTZ for dates
1126
+ - Always use TIMESTAMPTZ (not TIMESTAMP) for dates — store in UTC, convert in the app
1127
+ - Add NOT NULL constraints by default — make columns nullable only when NULL has business meaning
1128
+ - Use UUID (gen_random_uuid) for public-facing IDs, BIGSERIAL for internal primary keys
1129
+ - Define foreign keys with appropriate ON DELETE behavior: CASCADE, SET NULL, or RESTRICT
1130
+ - Add created_at and updated_at columns to every table — use triggers for updated_at
1131
+ - Use CHECK constraints for data validation: \`CHECK (price >= 0)\`, \`CHECK (status IN ('active','inactive'))\`
1132
+ - Normalize to 3NF by default — denormalize intentionally for read-heavy queries with measured need
1133
+
1134
+ ## Indexing Strategies
1135
+ - Index columns used in WHERE, JOIN, ORDER BY, and GROUP BY clauses
1136
+ - B-tree indexes (default) work for equality and range queries: =, <, >, BETWEEN, LIKE 'prefix%'
1137
+ - Composite indexes: put equality columns first, range columns last: \`(status, created_at)\`
1138
+ - Covering indexes include all columns a query needs — avoids heap lookups (INDEX ... INCLUDE)
1139
+ - Partial indexes for filtered queries: \`CREATE INDEX ON orders (user_id) WHERE status = 'pending'\`
1140
+ - GIN indexes for JSONB, full-text search, and array columns
1141
+ - Don't over-index — each index slows writes and consumes storage. Index what you query.
1142
+ - Use CONCURRENTLY for production index creation: \`CREATE INDEX CONCURRENTLY ...\`
1143
+
1144
+ ## Query Optimization
1145
+ - Use EXPLAIN ANALYZE to see actual execution plans — not just EXPLAIN (which estimates)
1146
+ - Look for: Seq Scan (missing index?), Nested Loop (N+1?), Sort (missing index?), high row estimates vs actuals
1147
+ - Avoid SELECT * — select only the columns you need
1148
+ - Use JOINs instead of subqueries where possible — the optimizer handles JOINs better
1149
+ - Avoid functions on indexed columns in WHERE: \`WHERE created_at > '2024-01-01'\` not \`WHERE YEAR(created_at) = 2024\`
1150
+ - Use EXISTS instead of IN for correlated subqueries — it short-circuits on first match
1151
+ - LIMIT early in subqueries to reduce the working set for outer queries
1152
+ - Use connection pooling (PgBouncer, built-in pool) — don't open a connection per request
1153
+
1154
+ ## Common Table Expressions (CTEs)
1155
+ - Use CTEs for readability: \`WITH active_users AS (SELECT ...) SELECT ... FROM active_users\`
1156
+ - CTEs are optimization fences in some databases — the optimizer may not push predicates into them
1157
+ - Recursive CTEs for hierarchical data: org charts, category trees, threaded comments
1158
+ - Pattern: \`WITH RECURSIVE tree AS (base UNION ALL SELECT ... FROM tree JOIN ... ) SELECT * FROM tree\`
1159
+ - Use CTEs to break complex queries into named, readable steps — each CTE is a logical unit
1160
+
1161
+ ## Window Functions
1162
+ - ROW_NUMBER() for pagination, deduplication, and picking the latest record per group
1163
+ - RANK() and DENSE_RANK() for ranking with ties (RANK skips, DENSE_RANK doesn't)
1164
+ - LAG/LEAD for comparing rows to previous/next rows: \`LAG(amount) OVER (ORDER BY date)\`
1165
+ - SUM/AVG/COUNT as window functions for running totals: \`SUM(amount) OVER (ORDER BY date)\`
1166
+ - Use PARTITION BY to compute within groups: \`ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)\`
1167
+ - FILTER clause for conditional aggregation: \`COUNT(*) FILTER (WHERE status = 'active')\`
1168
+
1169
+ ## Migrations
1170
+ - Use a migration tool: Flyway, Liquibase, golang-migrate, Prisma Migrate, or Knex
1171
+ - Every schema change is a numbered, version-controlled migration — never modify production DDL manually
1172
+ - Make migrations backward-compatible: add columns with defaults, avoid renaming in one step
1173
+ - Large table changes: add column → backfill → add constraint, not ALTER + NOT NULL in one migration
1174
+ - Always test migrations on a copy of production data before applying to production
1175
+ - Include both up and down migrations — even if you rarely use rollbacks
1176
+
1177
+ ## Avoiding N+1 Queries
1178
+ - N+1: fetching a list then querying related data per item — O(N) queries instead of O(1)
1179
+ - Fix with JOINs: \`SELECT users.*, orders.* FROM users JOIN orders ON ...\`
1180
+ - Fix with IN: \`SELECT * FROM orders WHERE user_id IN (1,2,3,...)\` — batch the lookups
1181
+ - ORMs: use eager loading (include, joinedload, preload) to fetch relations in one query
1182
+ - Monitor query counts in development — log the number of queries per request
1183
+
1184
+ ## Anti-Patterns
1185
+ - Don't use SELECT * in production queries — specify columns explicitly
1186
+ - Don't store CSV or JSON when you need relational data — normalize it
1187
+ - Don't skip foreign keys for "flexibility" — they enforce data integrity
1188
+ - Don't use OFFSET for deep pagination — use cursor-based (WHERE id > last_id) instead
1189
+ - Don't run schema changes without a migration tool — you'll lose track of database state
1190
+ - Don't optimize queries without EXPLAIN ANALYZE — measure before changing
1191
+ `,
1192
+ },
1193
+ {
1194
+ name: "supabase",
1195
+ description: "Auth, Row Level Security, edge functions, real-time, Postgres functions, storage",
1196
+ version: "1.0.0",
1197
+ author: "codemaxxing",
1198
+ tags: ["supabase", "postgres", "auth", "realtime", "edge-functions", "baas"],
1199
+ prompt: `# Supabase Expert
1200
+
1201
+ ## Auth Setup
1202
+ - Use Supabase Auth for email/password, magic link, OAuth (Google, GitHub, etc.)
1203
+ - Client: \`const { data, error } = await supabase.auth.signUp({ email, password })\`
1204
+ - Always check for errors after auth operations — don't assume success
1205
+ - Use onAuthStateChange listener to react to sign-in/sign-out events globally
1206
+ - Store user metadata in a separate profiles table linked by auth.uid() — don't overload auth.users
1207
+ - Use auth.getUser() (server-side verified) over auth.getSession() (client JWT only) for security
1208
+ - Configure email templates and redirect URLs in the Supabase dashboard
1209
+ - Set up proper redirect handling for OAuth: signInWithOAuth({ options: { redirectTo } })
1210
+
1211
+ ## Row Level Security (RLS)
1212
+ - ALWAYS enable RLS on every table: \`ALTER TABLE posts ENABLE ROW LEVEL SECURITY\`
1213
+ - Without RLS policies, NO rows are accessible — it's deny-by-default
1214
+ - Use auth.uid() in policies to scope access to the authenticated user
1215
+ - SELECT policy: \`CREATE POLICY "users read own" ON posts FOR SELECT USING (user_id = auth.uid())\`
1216
+ - INSERT policy: \`CREATE POLICY "users insert own" ON posts FOR INSERT WITH CHECK (user_id = auth.uid())\`
1217
+ - Use auth.jwt() -> 'user_role' for role-based access in policies
1218
+ - Test RLS policies thoroughly — use Supabase SQL editor with \`SET request.jwt.claims = ...\`
1219
+ - For public data, create a policy with \`USING (true)\` — but be intentional about it
1220
+
1221
+ ## Database & Postgres Functions
1222
+ - Use the Supabase client for CRUD: \`supabase.from("posts").select("*, author:profiles(name)")\`
1223
+ - Foreign key relations are automatic in .select() — use the relation name for joins
1224
+ - Use Postgres functions for complex operations: \`supabase.rpc("function_name", { param: value })\`
1225
+ - Write functions in SQL or PL/pgSQL: \`CREATE FUNCTION get_stats(...) RETURNS TABLE (...) AS $$ ... $$\`
1226
+ - Use SECURITY DEFINER functions to bypass RLS when needed (admin operations) — with caution
1227
+ - Set search_path in SECURITY DEFINER functions to prevent search path injection
1228
+ - Use database triggers for automated side effects: updated_at timestamps, audit logs, notifications
1229
+
1230
+ ## Edge Functions
1231
+ - Write edge functions in Deno/TypeScript — they run on Supabase's edge infrastructure
1232
+ - Use for: webhooks, third-party API calls, custom auth flows, scheduled jobs
1233
+ - Create a Supabase client inside edge functions with the service_role key for admin access
1234
+ - Validate incoming requests: check auth headers, parse and validate request bodies
1235
+ - Use Deno's built-in fetch for external API calls — edge functions have internet access
1236
+ - Deploy with \`supabase functions deploy function-name\`
1237
+ - Set secrets with \`supabase secrets set API_KEY=value\` — access via Deno.env.get()
1238
+
1239
+ ## Real-Time Subscriptions
1240
+ - Subscribe to database changes: \`supabase.channel("posts").on("postgres_changes", { event: "INSERT", schema: "public", table: "posts" }, callback).subscribe()\`
1241
+ - Filter subscriptions: \`filter: "user_id=eq.abc123"\` — don't subscribe to all rows
1242
+ - Use Broadcast for ephemeral messages (typing indicators, cursor positions)
1243
+ - Use Presence for tracking online users and their state
1244
+ - Unsubscribe when components unmount: \`supabase.removeChannel(channel)\`
1245
+ - RLS policies apply to real-time — users only receive changes they're authorized to see
1246
+
1247
+ ## Storage
1248
+ - Use Supabase Storage for file uploads: images, documents, videos
1249
+ - Create buckets with appropriate policies: public (avatars) vs private (documents)
1250
+ - Upload: \`supabase.storage.from("avatars").upload(path, file, { contentType })\`
1251
+ - Use signed URLs for time-limited access to private files: \`createSignedUrl(path, expiresIn)\`
1252
+ - Use image transformations for thumbnails: \`getPublicUrl(path, { transform: { width: 200 } })\`
1253
+ - Set file size limits and allowed MIME types per bucket in storage policies
1254
+
1255
+ ## Typed Client Generation
1256
+ - Generate TypeScript types from your database: \`supabase gen types typescript --project-id xxx > types/supabase.ts\`
1257
+ - Use generated types with the client: \`createClient<Database>(url, key)\`
1258
+ - Types provide autocomplete for table names, column names, and filter operations
1259
+ - Regenerate types after every migration — keep types in sync with the schema
1260
+ - Use Database['public']['Tables']['posts']['Row'] for row types in your app code
1261
+
1262
+ ## Anti-Patterns
1263
+ - Don't skip RLS — an unprotected table is a data breach waiting to happen
1264
+ - Don't use the service_role key on the client side — it bypasses all RLS
1265
+ - Don't query without filters on large tables — always scope your queries
1266
+ - Don't use real-time for everything — polling is simpler for low-frequency updates
1267
+ - Don't store business logic only in the client — use Postgres functions or edge functions
1268
+ - Don't hardcode Supabase URLs and keys — use environment variables
1269
+ `,
1270
+ },
1271
+ {
1272
+ name: "unity-csharp",
1273
+ description: "MonoBehaviour lifecycle, ScriptableObjects, ECS, object pooling, performance profiling",
1274
+ version: "1.0.0",
1275
+ author: "codemaxxing",
1276
+ tags: ["unity", "csharp", "gamedev", "ecs", "performance", "game-engine"],
1277
+ prompt: `# Unity & C# Game Development Expert
1278
+
1279
+ ## MonoBehaviour Lifecycle
1280
+ - Awake() → OnEnable() → Start() → FixedUpdate() → Update() → LateUpdate() → OnDisable() → OnDestroy()
1281
+ - Use Awake() for self-initialization (cache component references with GetComponent<T>())
1282
+ - Use Start() for initialization that depends on other objects being ready
1283
+ - Use FixedUpdate() for physics — it runs at a fixed timestep (default 50Hz), independent of framerate
1284
+ - Use Update() for input handling and non-physics game logic — runs once per frame
1285
+ - Use LateUpdate() for camera follow and anything that must happen after all Update() calls
1286
+ - Cache component references in Awake: \`private Rigidbody _rb; void Awake() => _rb = GetComponent<Rigidbody>();\`
1287
+ - Never use GetComponent in Update — it's an expensive lookup every frame
1288
+
1289
+ ## ScriptableObjects
1290
+ - Use ScriptableObjects for shared, data-driven assets: enemy stats, item definitions, game config
1291
+ - Create with: \`[CreateAssetMenu(fileName = "NewWeapon", menuName = "Game/Weapon")] public class WeaponData : ScriptableObject\`
1292
+ - ScriptableObjects persist in the project (not the scene) — changes in editor persist, changes at runtime don't (in builds)
1293
+ - Use them to decouple data from behavior — MonoBehaviours reference ScriptableObjects, not each other
1294
+ - Event channels: use ScriptableObject-based events to decouple systems without direct references
1295
+ - Pattern: ScriptableObject holds a list of listeners, Raise() notifies all — no singleton needed
1296
+
1297
+ ## Object Pooling
1298
+ - Instantiate/Destroy is expensive — pool frequently created/destroyed objects (bullets, particles, enemies)
1299
+ - Unity's built-in ObjectPool<T> (UnityEngine.Pool): \`new ObjectPool<GameObject>(createFunc, onGet, onRelease, onDestroy)\`
1300
+ - On Get: activate the object, reset its state (position, velocity, health)
1301
+ - On Release: deactivate the object, return it to the pool — don't Destroy it
1302
+ - Pre-warm pools at scene load to avoid frame hitches during gameplay
1303
+ - Use pool for particle systems, audio sources, and UI elements — not just game objects
1304
+
1305
+ ## Entity Component System (ECS)
1306
+ - Unity DOTS: Entities for data, Systems for logic, Components for pure data (no methods)
1307
+ - IComponentData structs are blittable data — no references, no managed types
1308
+ - SystemBase or ISystem process entities with matching component queries
1309
+ - Use Burst compiler for performance-critical systems — compiles to optimized native code
1310
+ - Jobs system for multi-threaded work: IJobEntity, IJobChunk for parallel processing
1311
+ - Use ECS for massive entity counts (10K+ units) — traditional MonoBehaviours for simpler needs
1312
+
1313
+ ## Physics Best Practices
1314
+ - Move Rigidbodies with forces (AddForce) or velocity — never transform.position for physics objects
1315
+ - Use layers and the collision matrix to control which objects interact
1316
+ - Use Physics.OverlapSphereNonAlloc() to avoid allocations in physics queries
1317
+ - Prefer discrete collision detection; use continuous only for fast-moving small objects
1318
+ - Use FixedUpdate for all physics code — Update runs at variable rate and causes jittery physics
1319
+ - Avoid moving static colliders at runtime — it rebuilds the physics tree (expensive)
1320
+
1321
+ ## Coroutines vs Async/Await
1322
+ - Coroutines (yield return): tied to MonoBehaviour, stop when GameObject is disabled/destroyed
1323
+ - Use yield return new WaitForSeconds(t) for delays, WaitUntil(() => condition) for polling
1324
+ - Async/await (UniTask recommended): proper cancellation, no MonoBehaviour dependency, awaitable
1325
+ - Use CancellationToken with async/await and link to destroyCancellationToken for auto-cleanup
1326
+ - Prefer async/await for complex async flows; coroutines for simple sequences and visual scripting
1327
+
1328
+ ## Asset Management
1329
+ - Use Addressables for loading assets on demand — reduces build size and startup time
1330
+ - Never use Resources.Load in production — it forces all Resources/ assets into the build
1331
+ - Unload unused assets: Addressables.Release() for counted references, Resources.UnloadUnusedAssets() as fallback
1332
+ - Use asset bundles / Addressable groups to organize content for DLC or streaming
1333
+ - Sprite atlases for UI and 2D — reduce draw calls by batching sprites into a single texture
1334
+
1335
+ ## Performance Profiling
1336
+ - Use Unity Profiler (Window > Analysis > Profiler) — identify CPU, GPU, memory, and rendering bottlenecks
1337
+ - Profile on target hardware — editor performance is not representative of builds
1338
+ - Watch for GC allocations in hot paths: use struct over class, avoid LINQ in Update, pre-allocate collections
1339
+ - Reduce draw calls: batching, atlasing, LODs, occlusion culling
1340
+ - Use Frame Debugger to inspect individual draw calls and shader passes
1341
+ - Profile with Deep Profile only when needed — it adds significant overhead
1342
+
1343
+ ## Anti-Patterns
1344
+ - Don't use Find("name") or FindObjectOfType at runtime — cache references or use events
1345
+ - Don't allocate in Update: no new List<T>, no LINQ, no string concatenation in hot loops
1346
+ - Don't use SendMessage — it's slow and stringly typed, use direct references or events
1347
+ - Don't put everything on one GameObject — split responsibilities across child objects
1348
+ - Don't ignore the profiler — gut feelings about performance are usually wrong
1349
+ - Don't use singletons for everything — use dependency injection or ScriptableObject events
1350
+ `,
1351
+ },
1352
+ {
1353
+ name: "git-workflow",
1354
+ description: "Conventional commits, branching strategies, PR best practices, rebase, hooks",
1355
+ version: "1.0.0",
1356
+ author: "codemaxxing",
1357
+ tags: ["git", "workflow", "commits", "branching", "code-review", "hooks"],
1358
+ prompt: `# Git Workflow Expert
1359
+
1360
+ ## Conventional Commits
1361
+ - Format: \`type(scope): description\` — e.g., \`feat(auth): add OAuth2 login flow\`
1362
+ - Types: feat (new feature), fix (bug fix), docs, style, refactor, perf, test, build, ci, chore
1363
+ - Breaking changes: add ! after type or BREAKING CHANGE in footer: \`feat(api)!: rename /users to /accounts\`
1364
+ - Scope is optional but helpful: module, component, or feature area
1365
+ - Description: imperative mood, lowercase, no period — "add login page" not "Added login page."
1366
+ - Body: wrap at 72 chars, explain WHAT and WHY (not HOW — the diff shows how)
1367
+ - Use commitlint + husky to enforce conventional commits in CI and locally
1368
+
1369
+ ## Branching Strategies
1370
+ - Trunk-based: short-lived feature branches (1-2 days), merge to main frequently, feature flags for WIP
1371
+ - GitFlow: main + develop + feature/ + release/ + hotfix/ — suited for versioned releases, more overhead
1372
+ - GitHub Flow: branch from main → PR → review → merge to main — simple, good for continuous deployment
1373
+ - For most teams: trunk-based or GitHub Flow — GitFlow adds complexity that slows teams down
1374
+ - Branch naming: type/description — \`feat/user-auth\`, \`fix/login-redirect\`, \`chore/update-deps\`
1375
+ - Delete branches after merge — don't accumulate stale branches
1376
+
1377
+ ## Pull Request Best Practices
1378
+ - Keep PRs small (under 400 lines changed) — large PRs get rubber-stamped, not reviewed
1379
+ - Write descriptive PR titles and descriptions: what changed, why, how to test
1380
+ - One concern per PR — don't mix a feature with a refactor with a bug fix
1381
+ - Add screenshots/recordings for UI changes
1382
+ - Self-review your PR before requesting review — catch obvious issues yourself
1383
+ - Request reviewers who own the affected code area
1384
+ - Respond to review comments promptly — don't let PRs go stale
1385
+
1386
+ ## Interactive Rebase
1387
+ - Use \`git rebase -i HEAD~N\` to clean up commits before opening a PR
1388
+ - Squash WIP commits into logical units: one commit per meaningful change
1389
+ - Reword commit messages to follow conventions: pick → reword
1390
+ - Fixup: absorb small fixes into the commit they belong to: pick → fixup
1391
+ - Never rebase commits that are already on shared branches (main, develop)
1392
+ - Prefer rebase over merge for feature branches — cleaner linear history
1393
+ - After rebase, force-push to your branch only: \`git push --force-with-lease\` (safer than --force)
1394
+
1395
+ ## Cherry-Pick & Bisect
1396
+ - Cherry-pick to apply specific commits to another branch: \`git cherry-pick <sha>\`
1397
+ - Use cherry-pick for hotfixes: fix on main, cherry-pick to release branch
1398
+ - Use -x flag to record the source commit: \`git cherry-pick -x <sha>\`
1399
+ - Bisect to find the commit that introduced a bug: \`git bisect start\`, \`git bisect bad\`, \`git bisect good <sha>\`
1400
+ - Automate bisect with a test script: \`git bisect run npm test\`
1401
+ - Bisect is O(log n) — it finds the bad commit in ~10 steps for 1000 commits
1402
+
1403
+ ## Git Hooks
1404
+ - Use husky (npm) or pre-commit (Python) to manage hooks across the team
1405
+ - pre-commit: lint staged files (lint-staged), format code, check for secrets
1406
+ - commit-msg: validate commit message format (commitlint)
1407
+ - pre-push: run tests, type-check — catch issues before they hit CI
1408
+ - Don't put slow operations in pre-commit — keep it under 5 seconds
1409
+ - Use lint-staged to only process staged files: \`"*.ts": ["eslint --fix", "prettier --write"]\`
1410
+
1411
+ ## .gitattributes & Configuration
1412
+ - Use .gitattributes for consistent line endings: \`* text=auto\` normalizes to LF
1413
+ - Mark binary files: \`*.png binary\`, \`*.zip binary\` — prevents diff/merge issues
1414
+ - Use .gitattributes for diff drivers: \`*.lockfile binary\` to skip noisy lockfile diffs
1415
+ - Use .gitignore for build artifacts, dependencies, env files, editor config
1416
+ - Global gitignore (~/.gitignore_global) for personal editor files (.vscode, .idea, .DS_Store)
1417
+ - Configure merge strategies per file: \`package-lock.json merge=ours\` to auto-resolve lockfile conflicts
1418
+
1419
+ ## Advanced Techniques
1420
+ - Use git stash for quick context switches: \`git stash push -m "WIP: feature X"\`
1421
+ - Use git worktree for working on multiple branches simultaneously without stashing
1422
+ - Use git reflog to recover lost commits — it tracks every HEAD movement for 90 days
1423
+ - Use git blame -w to ignore whitespace changes when tracking down who wrote a line
1424
+ - Use git log --all --graph --oneline for a visual branch/merge history
1425
+ - Use git diff --stat for a quick summary of changes before committing
1426
+
1427
+ ## Anti-Patterns
1428
+ - Don't commit directly to main — use branches and PRs for all changes
1429
+ - Don't use \`git add .\` blindly — review staged files to avoid committing secrets or artifacts
1430
+ - Don't rewrite shared history — rebase and amend only your own unpushed commits
1431
+ - Don't write commit messages like "fix" or "WIP" or "asdf" — future you will be confused
1432
+ - Don't keep long-lived branches — merge or rebase frequently to avoid painful conflicts
1433
+ - Don't skip code review — even small changes benefit from a second pair of eyes
480
1434
  `,
481
1435
  },
482
1436
  ];