From 6686a6dd1a319cd9a8814966832c585f25b86a56 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Mon, 13 Apr 2026 11:22:25 -0700 Subject: [PATCH 1/2] chore(skills): add code quality review skills and cleanup command --- .agents/skills/cleanup/SKILL.md | 25 ++ .agents/skills/emcn-design-review/SKILL.md | 315 ++++++++++++++++++ .../react-query-best-practices/SKILL.md | 54 +++ .../you-might-not-need-a-callback/SKILL.md | 51 +++ .../skills/you-might-not-need-a-memo/SKILL.md | 33 ++ .../skills/you-might-not-need-state/SKILL.md | 38 +++ .claude/commands/cleanup.md | 25 ++ .claude/commands/emcn-design-review.md | 100 ++++++ .../commands/react-query-best-practices.md | 54 +++ .../commands/you-might-not-need-a-callback.md | 35 ++ .claude/commands/you-might-not-need-a-memo.md | 33 ++ .claude/commands/you-might-not-need-state.md | 38 +++ .cursor/commands/cleanup.md | 20 ++ .cursor/commands/emcn-design-review.md | 95 ++++++ .../commands/react-query-best-practices.md | 49 +++ .../commands/you-might-not-need-a-callback.md | 30 ++ .cursor/commands/you-might-not-need-a-memo.md | 28 ++ .cursor/commands/you-might-not-need-state.md | 33 ++ 18 files changed, 1056 insertions(+) create mode 100644 .agents/skills/cleanup/SKILL.md create mode 100644 .agents/skills/emcn-design-review/SKILL.md create mode 100644 .agents/skills/react-query-best-practices/SKILL.md create mode 100644 .agents/skills/you-might-not-need-a-callback/SKILL.md create mode 100644 .agents/skills/you-might-not-need-a-memo/SKILL.md create mode 100644 .agents/skills/you-might-not-need-state/SKILL.md create mode 100644 .claude/commands/cleanup.md create mode 100644 .claude/commands/emcn-design-review.md create mode 100644 .claude/commands/react-query-best-practices.md create mode 100644 .claude/commands/you-might-not-need-a-callback.md create mode 100644 .claude/commands/you-might-not-need-a-memo.md create mode 100644 .claude/commands/you-might-not-need-state.md create mode 100644 .cursor/commands/cleanup.md create mode 100644 .cursor/commands/emcn-design-review.md create mode 100644 .cursor/commands/react-query-best-practices.md create mode 100644 .cursor/commands/you-might-not-need-a-callback.md create mode 100644 .cursor/commands/you-might-not-need-a-memo.md create mode 100644 .cursor/commands/you-might-not-need-state.md 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..2c5246ce27 --- /dev/null +++ b/.agents/skills/emcn-design-review/SKILL.md @@ -0,0 +1,315 @@ +--- +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 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 | +|-------------|---------| +| Primary action (create, save, submit) | `primary` | +| Cancel, close, secondary action | `default` | +| Delete, remove, destructive action | `destructive` | +| Toolbar/icon-only button | `ghost` | +| Toggle, mode switch | `ghost` or `outline` | +| Active/selected state | `active` | + +Sizes: `sm` (compact) or `md` (default). Never create custom button styles — use an existing variant. + +### Modals (Dialogs) +Use `Modal` + subcomponents. Never build custom dialog overlays. + +```tsx + + + Title + Content + + + + + + +``` + +Modal sizes: `sm` (440px, confirmations), `md` (500px, forms), `lg` (600px, content-heavy), `xl` (800px, complex editors), `full` (1200px, dashboards). + +Footer buttons: Cancel on left, primary action on right. + +### Delete Confirmations +Always use Modal with this pattern: + +```tsx + + + Delete {itemType} + +

Description of consequences

+

Warning about irreversibility

+ {/* Optional: confirmation text input for high-risk actions */} +
+ + + + +
+
+``` + +Rules: +- Title: "Delete {ItemType}" +- Include consequence description +- Use `text-[var(--text-error)]` for warning text +- Destructive button on the right +- 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. 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. + +### Badges +Use semantic color variants for status: + +| Status | Variant | +|--------|---------| +| Success, active, online | `green` | +| Error, failed, offline | `red` | +| Warning, processing | `amber` or `orange` | +| Info, default | `blue` | +| Neutral, draft, inactive | `gray` | +| Type labels | `type` | + +Use `dot` prop for status indicators. Use `icon` prop for icon badges. + +### 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 `` +- Use `Textarea` from emcn, never raw `