diff --git a/.agents/skills/cleanup/SKILL.md b/.agents/skills/cleanup/SKILL.md new file mode 100644 index 0000000000..54438a9b81 --- /dev/null +++ b/.agents/skills/cleanup/SKILL.md @@ -0,0 +1,25 @@ +--- +name: cleanup +description: Run all code quality skills in sequence — effects, memo, callbacks, state, React Query, and emcn design review +--- + +# Cleanup + +Arguments: +- scope: what to review (default: your current changes). Examples: "diff to main", "PR #123", "src/components/", "whole codebase" +- fix: whether to apply fixes (default: true). Set to false to only propose changes. + +User arguments: $ARGUMENTS + +## Steps + +Run each of these skills in order on the specified scope, passing through the scope and fix arguments. After each skill completes, move to the next. Do not skip any. + +1. `/you-might-not-need-an-effect $ARGUMENTS` +2. `/you-might-not-need-a-memo $ARGUMENTS` +3. `/you-might-not-need-a-callback $ARGUMENTS` +4. `/you-might-not-need-state $ARGUMENTS` +5. `/react-query-best-practices $ARGUMENTS` +6. `/emcn-design-review $ARGUMENTS` + +After all skills have run, output a summary of what was found and fixed (or proposed) across all six passes. diff --git a/.agents/skills/emcn-design-review/SKILL.md b/.agents/skills/emcn-design-review/SKILL.md new file mode 100644 index 0000000000..415a85046d --- /dev/null +++ b/.agents/skills/emcn-design-review/SKILL.md @@ -0,0 +1,335 @@ +--- +name: emcn-design-review +description: Review UI code for alignment with the emcn design system — components, tokens, patterns, and conventions +--- + +# EMCN Design Review + +Arguments: +- scope: what to review (default: your current changes). Examples: "diff to main", "PR #123", "src/components/", "whole codebase" +- fix: whether to apply fixes (default: true). Set to false to only propose changes. + +User arguments: $ARGUMENTS + +## Context + +This codebase uses **emcn**, a custom component library built on Radix UI primitives with CVA (class-variance-authority) variants and CSS variable design tokens. All UI must use emcn components and tokens — never raw HTML elements or hardcoded colors. + +## Steps + +1. Read the emcn barrel export at `apps/sim/components/emcn/components/index.ts` to know what's available +2. Read `apps/sim/app/_styles/globals.css` for the full set of CSS variable tokens +3. Analyze the specified scope against every rule below +4. If fix=true, apply the fixes. If fix=false, propose the fixes without applying. + +--- + +## Imports + +- Import components from `@/components/emcn`, never from subpaths +- Import icons from `@/components/emcn/icons` or `lucide-react` +- Import `cn` from `@/lib/core/utils/cn` for conditional class merging +- Import app-specific wrappers (Select, VerifiedBadge) from `@/components/ui` + +```tsx +// Good +import { Button, Modal, Badge } from '@/components/emcn' +// Bad +import { Button } from '@/components/emcn/components/button/button' +``` + +--- + +## Design Tokens (CSS Variables) + +Never use raw color values. Always use CSS variable tokens via Tailwind arbitrary values: `text-[var(--text-primary)]`, not `text-gray-500` or `#333`. The CSS variable pattern is canonical (1,700+ uses) — do not use Tailwind semantic classes like `text-muted-foreground`. + +### Text hierarchy +| Token | Use | +|-------|-----| +| `text-[var(--text-primary)]` | Main content text | +| `text-[var(--text-secondary)]` | Secondary/supporting text | +| `text-[var(--text-tertiary)]` | Tertiary text | +| `text-[var(--text-muted)]` | Disabled, placeholder text | +| `text-[var(--text-icon)]` | Icon tinting | +| `text-[var(--text-inverse)]` | Text on dark backgrounds | +| `text-[var(--text-error)]` | Error/warning messages | + +### Surfaces (elevation) +| Token | Use | +|-------|-----| +| `bg-[var(--bg)]` | Page background | +| `bg-[var(--surface-2)]` through `bg-[var(--surface-7)]` | Increasing elevation | +| `bg-[var(--surface-hover)]` | Hover state backgrounds | +| `bg-[var(--surface-active)]` | Active/selected backgrounds | + +### Borders +| Token | Use | +|-------|-----| +| `border-[var(--border)]` | Default borders | +| `border-[var(--border-1)]` | Stronger borders (inputs, cards) | +| `border-[var(--border-muted)]` | Subtle dividers | + +### Status +| Token | Use | +|-------|-----| +| `--success` | Success states | +| `--error` | Error states | +| `--caution` | Warning states | + +### Brand +| Token | Use | +|-------|-----| +| `--brand-secondary` | Brand color | +| `--brand-accent` | Accent/CTA color | + +### Shadows +Use shadow tokens, never raw box-shadow values: +- `shadow-subtle`, `shadow-medium`, `shadow-overlay` +- `shadow-kbd`, `shadow-card` + +### Z-Index +Use z-index tokens for layering: +- `z-[var(--z-dropdown)]` (100), `z-[var(--z-modal)]` (200), `z-[var(--z-popover)]` (300), `z-[var(--z-tooltip)]` (400), `z-[var(--z-toast)]` (500) + +--- + +## Component Usage Rules + +### Buttons +Available variants: `default`, `primary`, `destructive`, `ghost`, `outline`, `active`, `secondary`, `tertiary`, `subtle`, `ghost-secondary`, `3d` + +| Action type | Variant | Frequency | +|-------------|---------|-----------| +| Toolbar, icon-only, utility actions | `ghost` | Most common (28%) | +| Primary action (create, save, submit) | `primary` | Very common (24%) | +| Cancel, close, secondary action | `default` | Common | +| Delete, remove, destructive action | `destructive` | Targeted use only | +| Active/selected state | `active` | Targeted use only | +| Toggle, mode switch | `outline` | Moderate | + +Sizes: `sm` (compact, 32% of buttons) or `md` (default, used when no size specified). Never create custom button styles — use an existing variant. + +Buttons without an explicit variant prop get `default` styling. This is acceptable for cancel/secondary actions. + +### Modals (Dialogs) +Use `Modal` + subcomponents. Never build custom dialog overlays. + +```tsx + + + Title + Content + + + + + + +``` + +Modal sizes by frequency: `sm` (440px, most common — confirmations and simple dialogs), `md` (500px, forms), `lg` (600px, content-heavy), `xl` (800px, rare), `full` (1200px, rare). + +Footer buttons: Cancel on left (`variant="default"`), primary action on right. This pattern is followed 100% across the codebase. + +### Delete/Remove Confirmations +Always use Modal with `size="sm"`. The established pattern: + +```tsx + + + Delete {itemType} + +

Description of consequences

+

Warning about irreversibility

+
+ + + + +
+
+``` + +Rules: +- Title: "Delete {ItemType}" or "Remove {ItemType}" (use "Remove" for membership/association changes) +- Include consequence description +- Use `text-[var(--text-error)]` for warning text when the action is irreversible +- `variant="destructive"` for the action button (100% compliance) +- `variant="default"` for cancel (100% compliance) +- Cancel left, destructive right (100% compliance) +- For high-risk deletes (workspaces), require typing the name to confirm +- Include recovery info if soft-delete: "You can restore it from Recently Deleted in Settings" + +### Toast Notifications +Use the imperative `toast` API from `@/components/emcn`. Never build custom notification UI. + +```tsx +import { toast } from '@/components/emcn' + +toast.success('Item saved') +toast.error('Something went wrong') +toast.success('Deleted', { action: { label: 'Undo', onClick: handleUndo } }) +``` + +Variants: `default`, `success`, `error`. Auto-dismiss after 5s. Supports optional action buttons with callbacks. + +### Badges +Use semantic color variants for status: + +| Status | Variant | Usage | +|--------|---------|-------| +| Error, failed, disconnected | `red` | Most common (15 uses) | +| Metadata, roles, auth types, scopes | `gray-secondary` | Very common (12 uses) | +| Type annotations (TS types, field types) | `type` | Very common (12 uses) | +| Success, active, enabled, running | `green` | Common (7 uses) | +| Neutral, default, unknown | `gray` | Common (6 uses) | +| Outline, parameters, public | `outline` | Moderate (6 uses) | +| Warning, processing | `amber` | Moderate (5 uses) | +| Paused, warning | `orange` | Occasional | +| Info, queued | `blue` | Occasional | +| Data types (arrays) | `purple` | Occasional | +| Generic with border | `default` | Occasional | + +Use `dot` prop for status indicators (19 instances in codebase). `icon` prop is available but rarely used. + +### Tooltips +Use `Tooltip` from emcn with namespace pattern: + +```tsx + + + + + Helpful text + +``` + +Use tooltips for icon-only buttons and truncated text. Don't tooltip self-explanatory elements. + +### Popovers +Use for filters, option menus, and nested navigation: + +```tsx + + + + + + Section Title + + Item Label + + + + +``` + +### Dropdown Menus +Use for context menus and action menus: + +```tsx + + + + + + Edit + + + Delete + + + +``` + +Destructive items go last, after a separator, in error color. + +### Forms +Use `FormField` wrapper for labeled inputs: + +```tsx + + setName(e.target.value)} /> + +``` + +Rules: +- Use `Input` from emcn, never raw `` (exception: hidden file inputs) +- Use `Textarea` from emcn, never raw `