From c8251a989ef1f655c7b4970ca53181dc4f9a8f57 Mon Sep 17 00:00:00 2001 From: N1C4T Date: Sat, 17 Jan 2026 19:55:24 +0400 Subject: [PATCH] refactor: minor changes to umami events logic --- .gitignore | 2 +- AGENT.md | 123 +++++++++++++++++++++++ src/components/app/AppItem.tsx | 7 ++ src/components/distro/DistroSelector.tsx | 3 +- 4 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 AGENT.md diff --git a/.gitignore b/.gitignore index e8e3837..2ef1da1 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,4 @@ yarn-error.log* next-env.d.ts # local notes -AGENT.md +# AGENT.md diff --git a/AGENT.md b/AGENT.md new file mode 100644 index 0000000..9cf7e94 --- /dev/null +++ b/AGENT.md @@ -0,0 +1,123 @@ +# TuxMate - Agent Guidelines + +This document helps AI assistants understand how to work with this codebase. + +## Project Overview + +TuxMate is a Linux bulk app installer web app. Users select apps, pick their distro, and get a ready-to-run terminal command. + +**Stack**: Next.js 14, TypeScript, Tailwind CSS, GSAP animations + +## Code Style + +### Comments + +Single-line `//` comments only. No JSDoc blocks. + +**Good:** +```ts +// Everything the app needs to work +export function useLinuxInit() { ... } + +// Quick one-liner for copy-paste warriors +export function generateSimpleCommand() { ... } + +// Vim-style keyboard navigation. Because real devs don't use mice. +export function useKeyboardNavigation() { ... } +``` + +**Never do this:** +```ts +/** + * This is a multi-line JSDoc block. + * We don't use these here. + */ +``` + +### Tone + +Comments should sound like a senior dev wrote them. Brief, practical, occasionally witty. + +- ✅ "Arch with AUR packages - this is where it gets fun" +- ✅ "Memoized because React was having a moment" +- ❌ "This function handles the complex orchestration of..." +- ❌ "Leveraging advanced patterns to optimize..." + +### Formatting + +- `'use client';` at top of client components +- CSS variables for theming: `var(--bg-primary)`, `var(--text-muted)`, etc. +- Tailwind for utilities, CSS variables for colors +- GSAP for entrance animations + +## Key Patterns + +### State Management +- All state lives in hooks (`useLinuxInit`, `useTheme`, etc.) +- localStorage persistence with hydration handling +- No external state libraries + +### Distro Handling +- Configs in `src/lib/data.ts` +- Each distro: id, name, color, icon, installPrefix +- Package names: `app.targets[distroId]` + +### AUR Detection +- `src/lib/aur.ts` handles Arch AUR package detection +- Patterns: `-bin`, `-git`, `-appimage` suffixes +- Known AUR list for edge cases + +### Nix Handling +- `src/lib/nixUnfree.ts` detects unfree packages (Discord, Slack, Spotify, Steam, etc.) +- Nix outputs declarative config, not shell scripts +- Preview: clean config snippet +- Download: includes unfree warning comment if needed +- Set `KNOWN_UNFREE_PACKAGES` contains lowercase package names +- **Verify Licenses**: Always check `nixpkgs` for license status. If `free = false`, add to `KNOWN_UNFREE_PACKAGES`. + - Example: `heroic` is GPLv3 (free), `discord` is unfree. Don't guess. + +### Command Generation +- `useLinuxInit` generates clipboard one-liner (preview) +- `generateInstallScript` creates downloadable files +- Nix: downloads `configuration.nix`, others download `.sh` +- Each distro has its own generator in `src/lib/scripts/` + +## File Structure + +``` +src/ +├── app/ # Next.js pages +├── components/ # UI by domain +│ ├── app/ # App grid (CategorySection, AppItem) +│ ├── command/ # Footer, drawer, shortcuts +│ ├── common/ # Tooltip, GlobalStyles +│ ├── distro/ # Distro selector +│ ├── header/ # Help modal, links +│ └── ui/ # Theme toggle +├── hooks/ # Custom hooks +└── lib/ # Data, utilities, scripts + ├── aur.ts # Arch AUR package detection + ├── nixUnfree.ts # Nix unfree package detection + ├── data.ts # All apps and distro configs + └── scripts/ # Per-distro generators +``` + +## Don't + +- No JSDoc blocks +- No "educational" comments explaining obvious things +- No buzzwords (leveraging, orchestrating, paradigm) +- No unnecessary abstractions +- Don't ignore existing patterns +- Don't add unused exports (dead code) +- Don't duplicate logic across files - centralize + +## Do + +- Keep comments concise +- Match existing code style +- Test on mobile (drawer = bottom sheet) +- Use distro brand color for accents +- Persist preferences to localStorage +- One file per distro in `scripts/` (e.g., `nix.ts`, `arch.ts`) +- Follow AUR pattern when adding distro-specific detection diff --git a/src/components/app/AppItem.tsx b/src/components/app/AppItem.tsx index 4eff6ee..e9ebc9d 100644 --- a/src/components/app/AppItem.tsx +++ b/src/components/app/AppItem.tsx @@ -5,6 +5,7 @@ import { Check } from 'lucide-react'; import { distros, type DistroId, type AppData } from '@/lib/data'; import { isAurPackage } from '@/lib/aur'; import { AppIcon } from './AppIcon'; +// import { analytics } from '@/lib/analytics'; // Uncomment to enable app selection tracking /** * Individual app row in the category list. @@ -93,6 +94,12 @@ export const AppItem = memo(function AppItem({ onFocus?.(); if (isAvailable) { onToggle(); + // Umami tracking disabled to save quota + // if (isSelected) { + // analytics.appDeselected(app.name, app.category || '', selectedDistro); + // } else { + // analytics.appSelected(app.name, app.category || '', selectedDistro); + // } } }} > diff --git a/src/components/distro/DistroSelector.tsx b/src/components/distro/DistroSelector.tsx index da63bb5..13f25e7 100644 --- a/src/components/distro/DistroSelector.tsx +++ b/src/components/distro/DistroSelector.tsx @@ -4,6 +4,7 @@ import { useState, useEffect, useRef } from 'react'; import { createPortal } from 'react-dom'; import { Check, ChevronDown } from 'lucide-react'; import { distros, type DistroId } from '@/lib/data'; +import { analytics } from '@/lib/analytics'; import { DistroIcon } from './DistroIcon'; /** @@ -78,7 +79,7 @@ export function DistroSelector({ {distros.map((distro, i) => (