Skip to content

Commit 0ac0539

Browse files
authored
v0.6.40: mothership tool loop, new skills, agiloft, STS, IAM integrations, jira forms endpoints
2 parents e3d0e74 + 8a8bc1b commit 0ac0539

File tree

732 files changed

+82542
-22989
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

732 files changed

+82542
-22989
lines changed

.agents/skills/cleanup/SKILL.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
name: cleanup
3+
description: Run all code quality skills in sequence — effects, memo, callbacks, state, React Query, and emcn design review
4+
---
5+
6+
# Cleanup
7+
8+
Arguments:
9+
- scope: what to review (default: your current changes). Examples: "diff to main", "PR #123", "src/components/", "whole codebase"
10+
- fix: whether to apply fixes (default: true). Set to false to only propose changes.
11+
12+
User arguments: $ARGUMENTS
13+
14+
## Steps
15+
16+
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.
17+
18+
1. `/you-might-not-need-an-effect $ARGUMENTS`
19+
2. `/you-might-not-need-a-memo $ARGUMENTS`
20+
3. `/you-might-not-need-a-callback $ARGUMENTS`
21+
4. `/you-might-not-need-state $ARGUMENTS`
22+
5. `/react-query-best-practices $ARGUMENTS`
23+
6. `/emcn-design-review $ARGUMENTS`
24+
25+
After all skills have run, output a summary of what was found and fixed (or proposed) across all six passes.
Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
---
2+
name: emcn-design-review
3+
description: Review UI code for alignment with the emcn design system — components, tokens, patterns, and conventions
4+
---
5+
6+
# EMCN Design Review
7+
8+
Arguments:
9+
- scope: what to review (default: your current changes). Examples: "diff to main", "PR #123", "src/components/", "whole codebase"
10+
- fix: whether to apply fixes (default: true). Set to false to only propose changes.
11+
12+
User arguments: $ARGUMENTS
13+
14+
## Context
15+
16+
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.
17+
18+
## Steps
19+
20+
1. Read the emcn barrel export at `apps/sim/components/emcn/components/index.ts` to know what's available
21+
2. Read `apps/sim/app/_styles/globals.css` for the full set of CSS variable tokens
22+
3. Analyze the specified scope against every rule below
23+
4. If fix=true, apply the fixes. If fix=false, propose the fixes without applying.
24+
25+
---
26+
27+
## Imports
28+
29+
- Import components from `@/components/emcn`, never from subpaths
30+
- Import icons from `@/components/emcn/icons` or `lucide-react`
31+
- Import `cn` from `@/lib/core/utils/cn` for conditional class merging
32+
- Import app-specific wrappers (Select, VerifiedBadge) from `@/components/ui`
33+
34+
```tsx
35+
// Good
36+
import { Button, Modal, Badge } from '@/components/emcn'
37+
// Bad
38+
import { Button } from '@/components/emcn/components/button/button'
39+
```
40+
41+
---
42+
43+
## Design Tokens (CSS Variables)
44+
45+
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`.
46+
47+
### Text hierarchy
48+
| Token | Use |
49+
|-------|-----|
50+
| `text-[var(--text-primary)]` | Main content text |
51+
| `text-[var(--text-secondary)]` | Secondary/supporting text |
52+
| `text-[var(--text-tertiary)]` | Tertiary text |
53+
| `text-[var(--text-muted)]` | Disabled, placeholder text |
54+
| `text-[var(--text-icon)]` | Icon tinting |
55+
| `text-[var(--text-inverse)]` | Text on dark backgrounds |
56+
| `text-[var(--text-error)]` | Error/warning messages |
57+
58+
### Surfaces (elevation)
59+
| Token | Use |
60+
|-------|-----|
61+
| `bg-[var(--bg)]` | Page background |
62+
| `bg-[var(--surface-2)]` through `bg-[var(--surface-7)]` | Increasing elevation |
63+
| `bg-[var(--surface-hover)]` | Hover state backgrounds |
64+
| `bg-[var(--surface-active)]` | Active/selected backgrounds |
65+
66+
### Borders
67+
| Token | Use |
68+
|-------|-----|
69+
| `border-[var(--border)]` | Default borders |
70+
| `border-[var(--border-1)]` | Stronger borders (inputs, cards) |
71+
| `border-[var(--border-muted)]` | Subtle dividers |
72+
73+
### Status
74+
| Token | Use |
75+
|-------|-----|
76+
| `--success` | Success states |
77+
| `--error` | Error states |
78+
| `--caution` | Warning states |
79+
80+
### Brand
81+
| Token | Use |
82+
|-------|-----|
83+
| `--brand-secondary` | Brand color |
84+
| `--brand-accent` | Accent/CTA color |
85+
86+
### Shadows
87+
Use shadow tokens, never raw box-shadow values:
88+
- `shadow-subtle`, `shadow-medium`, `shadow-overlay`
89+
- `shadow-kbd`, `shadow-card`
90+
91+
### Z-Index
92+
Use z-index tokens for layering:
93+
- `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)
94+
95+
---
96+
97+
## Component Usage Rules
98+
99+
### Buttons
100+
Available variants: `default`, `primary`, `destructive`, `ghost`, `outline`, `active`, `secondary`, `tertiary`, `subtle`, `ghost-secondary`, `3d`
101+
102+
| Action type | Variant | Frequency |
103+
|-------------|---------|-----------|
104+
| Toolbar, icon-only, utility actions | `ghost` | Most common (28%) |
105+
| Primary action (create, save, submit) | `primary` | Very common (24%) |
106+
| Cancel, close, secondary action | `default` | Common |
107+
| Delete, remove, destructive action | `destructive` | Targeted use only |
108+
| Active/selected state | `active` | Targeted use only |
109+
| Toggle, mode switch | `outline` | Moderate |
110+
111+
Sizes: `sm` (compact, 32% of buttons) or `md` (default, used when no size specified). Never create custom button styles — use an existing variant.
112+
113+
Buttons without an explicit variant prop get `default` styling. This is acceptable for cancel/secondary actions.
114+
115+
### Modals (Dialogs)
116+
Use `Modal` + subcomponents. Never build custom dialog overlays.
117+
118+
```tsx
119+
<Modal open={open} onOpenChange={setOpen}>
120+
<ModalContent size="sm">
121+
<ModalHeader>Title</ModalHeader>
122+
<ModalBody>Content</ModalBody>
123+
<ModalFooter>
124+
<Button variant="default" onClick={() => setOpen(false)}>Cancel</Button>
125+
<Button variant="primary" onClick={handleSubmit}>Save</Button>
126+
</ModalFooter>
127+
</ModalContent>
128+
</Modal>
129+
```
130+
131+
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).
132+
133+
Footer buttons: Cancel on left (`variant="default"`), primary action on right. This pattern is followed 100% across the codebase.
134+
135+
### Delete/Remove Confirmations
136+
Always use Modal with `size="sm"`. The established pattern:
137+
138+
```tsx
139+
<Modal open={open} onOpenChange={setOpen}>
140+
<ModalContent size="sm">
141+
<ModalHeader>Delete {itemType}</ModalHeader>
142+
<ModalBody>
143+
<p>Description of consequences</p>
144+
<p className="text-[var(--text-error)]">Warning about irreversibility</p>
145+
</ModalBody>
146+
<ModalFooter>
147+
<Button variant="default" onClick={() => setOpen(false)}>Cancel</Button>
148+
<Button variant="destructive" onClick={handleDelete} disabled={isDeleting}>
149+
Delete
150+
</Button>
151+
</ModalFooter>
152+
</ModalContent>
153+
</Modal>
154+
```
155+
156+
Rules:
157+
- Title: "Delete {ItemType}" or "Remove {ItemType}" (use "Remove" for membership/association changes)
158+
- Include consequence description
159+
- Use `text-[var(--text-error)]` for warning text when the action is irreversible
160+
- `variant="destructive"` for the action button (100% compliance)
161+
- `variant="default"` for cancel (100% compliance)
162+
- Cancel left, destructive right (100% compliance)
163+
- For high-risk deletes (workspaces), require typing the name to confirm
164+
- Include recovery info if soft-delete: "You can restore it from Recently Deleted in Settings"
165+
166+
### Toast Notifications
167+
Use the imperative `toast` API from `@/components/emcn`. Never build custom notification UI.
168+
169+
```tsx
170+
import { toast } from '@/components/emcn'
171+
172+
toast.success('Item saved')
173+
toast.error('Something went wrong')
174+
toast.success('Deleted', { action: { label: 'Undo', onClick: handleUndo } })
175+
```
176+
177+
Variants: `default`, `success`, `error`. Auto-dismiss after 5s. Supports optional action buttons with callbacks.
178+
179+
### Badges
180+
Use semantic color variants for status:
181+
182+
| Status | Variant | Usage |
183+
|--------|---------|-------|
184+
| Error, failed, disconnected | `red` | Most common (15 uses) |
185+
| Metadata, roles, auth types, scopes | `gray-secondary` | Very common (12 uses) |
186+
| Type annotations (TS types, field types) | `type` | Very common (12 uses) |
187+
| Success, active, enabled, running | `green` | Common (7 uses) |
188+
| Neutral, default, unknown | `gray` | Common (6 uses) |
189+
| Outline, parameters, public | `outline` | Moderate (6 uses) |
190+
| Warning, processing | `amber` | Moderate (5 uses) |
191+
| Paused, warning | `orange` | Occasional |
192+
| Info, queued | `blue` | Occasional |
193+
| Data types (arrays) | `purple` | Occasional |
194+
| Generic with border | `default` | Occasional |
195+
196+
Use `dot` prop for status indicators (19 instances in codebase). `icon` prop is available but rarely used.
197+
198+
### Tooltips
199+
Use `Tooltip` from emcn with namespace pattern:
200+
201+
```tsx
202+
<Tooltip.Root>
203+
<Tooltip.Trigger asChild>
204+
<Button variant="ghost">{icon}</Button>
205+
</Tooltip.Trigger>
206+
<Tooltip.Content>Helpful text</Tooltip.Content>
207+
</Tooltip.Root>
208+
```
209+
210+
Use tooltips for icon-only buttons and truncated text. Don't tooltip self-explanatory elements.
211+
212+
### Popovers
213+
Use for filters, option menus, and nested navigation:
214+
215+
```tsx
216+
<Popover open={open} onOpenChange={setOpen} size="sm">
217+
<PopoverTrigger asChild>
218+
<Button variant="ghost">Trigger</Button>
219+
</PopoverTrigger>
220+
<PopoverContent side="bottom" align="end" minWidth={160}>
221+
<PopoverSection>Section Title</PopoverSection>
222+
<PopoverItem active={isActive} onClick={handleClick}>
223+
Item Label
224+
</PopoverItem>
225+
<PopoverDivider />
226+
</PopoverContent>
227+
</Popover>
228+
```
229+
230+
### Dropdown Menus
231+
Use for context menus and action menus:
232+
233+
```tsx
234+
<DropdownMenu>
235+
<DropdownMenuTrigger asChild>
236+
<Button variant="ghost">
237+
<MoreHorizontal className="h-[14px] w-[14px]" />
238+
</Button>
239+
</DropdownMenuTrigger>
240+
<DropdownMenuContent align="end">
241+
<DropdownMenuItem onClick={handleEdit}>Edit</DropdownMenuItem>
242+
<DropdownMenuSeparator />
243+
<DropdownMenuItem onClick={handleDelete} className="text-[var(--text-error)]">
244+
Delete
245+
</DropdownMenuItem>
246+
</DropdownMenuContent>
247+
</DropdownMenu>
248+
```
249+
250+
Destructive items go last, after a separator, in error color.
251+
252+
### Forms
253+
Use `FormField` wrapper for labeled inputs:
254+
255+
```tsx
256+
<FormField label="Name" htmlFor="name" error={errors.name} optional>
257+
<Input id="name" value={name} onChange={e => setName(e.target.value)} />
258+
</FormField>
259+
```
260+
261+
Rules:
262+
- Use `Input` from emcn, never raw `<input>` (exception: hidden file inputs)
263+
- Use `Textarea` from emcn, never raw `<textarea>`
264+
- Use `FormField` for label + input + error layout
265+
- Mark optional fields with `optional` prop
266+
- Show errors inline below the input
267+
- Use `Combobox` for searchable selects
268+
- Use `TagInput` for multi-value inputs
269+
270+
### Loading States
271+
Use `Skeleton` for content placeholders:
272+
273+
```tsx
274+
<Skeleton className="h-5 w-[200px] rounded-md" />
275+
```
276+
277+
Rules:
278+
- Mirror the actual UI structure with skeletons
279+
- Match exact dimensions of the final content
280+
- Use `rounded-md` to match component radius
281+
- Stack multiple skeletons for lists
282+
283+
### Icons
284+
Standard sizing — `h-[14px] w-[14px]` is the dominant pattern (400+ uses):
285+
286+
```tsx
287+
<Icon className="h-[14px] w-[14px] text-[var(--text-icon)]" />
288+
```
289+
290+
Size scale by frequency:
291+
1. `h-[14px] w-[14px]` — default for inline icons (most common)
292+
2. `h-[16px] w-[16px]` — slightly larger inline icons
293+
3. `h-3 w-3` (12px) — compact/tight spaces
294+
4. `h-4 w-4` (16px) — Tailwind equivalent, also common
295+
5. `h-3.5 w-3.5` (14px) — Tailwind equivalent of 14px
296+
6. `h-5 w-5` (20px) — larger icons, section headers
297+
298+
Use `text-[var(--text-icon)]` for icon color (113+ uses in codebase).
299+
300+
---
301+
302+
## Styling Rules
303+
304+
1. **Use `cn()` for conditional classes**: `cn('base', condition && 'conditional')` — never template literal concatenation like `` `base ${condition ? 'active' : ''}` ``
305+
2. **Inline styles**: Avoid. Exception: dynamic values that can't be expressed as Tailwind classes (e.g., `style={{ width: dynamicVar }}` or CSS variable references). Never use inline styles for colors or static values.
306+
3. **Never hardcode colors**: Use CSS variable tokens. Never `text-gray-500`, `bg-red-100`, `#fff`, or `rgb()`. Always `text-[var(--text-*)]`, `bg-[var(--surface-*)]`, etc.
307+
4. **Never use Tailwind semantic color classes**: Use `text-[var(--text-muted)]` not `text-muted-foreground`. The CSS variable pattern is canonical.
308+
5. **Never use global styles**: Keep all styling local to components
309+
6. **Hover states**: Use `hover-hover:` pseudo-class for hover-capable devices
310+
7. **Transitions**: Use `transition-colors` for color changes, `transition-colors duration-100` for fast hover
311+
8. **Border radius**: `rounded-lg` (large cards), `rounded-md` (medium), `rounded-sm` (small), `rounded-xs` (tiny)
312+
9. **Typography**: Use semantic sizes — `text-small` (13px), `text-caption` (12px), `text-xs` (11px), `text-micro` (10px)
313+
10. **Font weight**: Use `font-medium` for emphasis, avoid `font-bold` unless for headings
314+
11. **Spacing**: Use Tailwind gap/padding utilities. Common patterns: `gap-2`, `gap-3`, `px-4 py-2.5`
315+
316+
---
317+
318+
## Anti-patterns to flag
319+
320+
- Raw HTML `<button>` instead of Button component (exception: inside Radix primitives)
321+
- Raw HTML `<input>` instead of Input component (exception: hidden file inputs, read-only checkboxes in markdown)
322+
- Hardcoded Tailwind default colors (`text-gray-*`, `bg-red-*`, `text-blue-*`)
323+
- Hex values in className (`bg-[#fff]`, `text-[#333]`)
324+
- Tailwind semantic classes (`text-muted-foreground`) instead of CSS variables (`text-[var(--text-muted)]`)
325+
- Custom modal/dialog implementations instead of `Modal`
326+
- Custom toast/notification implementations instead of `toast`
327+
- Inline styles for colors or static values (dynamic values are acceptable)
328+
- Template literal className concatenation instead of `cn()`
329+
- Wrong button variant for the action type
330+
- Missing loading/skeleton states
331+
- Missing error states on forms
332+
- Importing from emcn subpaths instead of barrel export
333+
- Using arbitrary z-index (`z-50`, `z-[9999]`) instead of z-index tokens
334+
- Custom shadows instead of shadow tokens
335+
- Icon sizes that don't follow the established scale (default to `h-[14px] w-[14px]`)

0 commit comments

Comments
 (0)