Skip to content
Merged
35 changes: 35 additions & 0 deletions .claude/rules/emcn-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
paths:
- "apps/sim/components/emcn/**"
---

# EMCN Components

Import from `@/components/emcn`, never from subpaths (except CSS files).

## CVA vs Direct Styles

**Use CVA when:** 2+ variants (primary/secondary, sm/md/lg)

```tsx
const buttonVariants = cva('base-classes', {
variants: { variant: { default: '...', primary: '...' } }
})
export { Button, buttonVariants }
```

**Use direct className when:** Single consistent style, no variations

```tsx
function Label({ className, ...props }) {
return <Primitive className={cn('style-classes', className)} {...props} />
}
```

## Rules

- Use Radix UI primitives for accessibility
- Export component and variants (if using CVA)
- TSDoc with usage examples
- Consistent tokens: `font-medium`, `text-[12px]`, `rounded-[4px]`
- `transition-colors` for hover states
13 changes: 13 additions & 0 deletions .claude/rules/global.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Global Standards

## Logging
Import `createLogger` from `sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Import path should use @sim/logger to match existing convention based on the context provided

Suggested change
Import `createLogger` from `sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`.
Import `createLogger` from `@sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: .claude/rules/global.md
Line: 4:4

Comment:
**style:** Import path should use `@sim/logger` to match existing convention based on the context provided

```suggestion
Import `createLogger` from `@sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`.
```

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.


## Comments
Use TSDoc for documentation. No `====` separators. No non-TSDoc comments.

## Styling
Never update global styles. Keep all styling local to components.

## Package Manager
Use `bun` and `bunx`, not `npm` and `npx`.
56 changes: 56 additions & 0 deletions .claude/rules/sim-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
paths:
- "apps/sim/**"
---

# Sim App Architecture

## Core Principles
1. **Single Responsibility**: Each component, hook, store has one clear purpose
2. **Composition Over Complexity**: Break down complex logic into smaller pieces
3. **Type Safety First**: TypeScript interfaces for all props, state, return types
4. **Predictable State**: Zustand for global state, useState for UI-only concerns

## Root-Level Structure

```
apps/sim/
├── app/ # Next.js app router (pages, API routes)
├── blocks/ # Block definitions and registry
├── components/ # Shared UI (emcn/, ui/)
├── executor/ # Workflow execution engine
├── hooks/ # Shared hooks (queries/, selectors/)
├── lib/ # App-wide utilities
├── providers/ # LLM provider integrations
├── stores/ # Zustand stores
├── tools/ # Tool definitions
└── triggers/ # Trigger definitions
```

## Feature Organization

Features live under `app/workspace/[workspaceId]/`:

```
feature/
├── components/ # Feature components
├── hooks/ # Feature-scoped hooks
├── utils/ # Feature-scoped utilities (2+ consumers)
├── feature.tsx # Main component
└── page.tsx # Next.js page entry
```

## Naming Conventions
- **Components**: PascalCase (`WorkflowList`)
- **Hooks**: `use` prefix (`useWorkflowOperations`)
- **Files**: kebab-case (`workflow-list.tsx`)
- **Stores**: `stores/feature/store.ts`
- **Constants**: SCREAMING_SNAKE_CASE
- **Interfaces**: PascalCase with suffix (`WorkflowListProps`)

## Utils Rules

- **Never create `utils.ts` for single consumer** - inline it
- **Create `utils.ts` when** 2+ files need the same helper
- **Check existing sources** before duplicating (`lib/` has many utilities)
- **Location**: `lib/` (app-wide) → `feature/utils/` (feature-scoped) → inline (single-use)
48 changes: 48 additions & 0 deletions .claude/rules/sim-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
paths:
- "apps/sim/**/*.tsx"
---

# Component Patterns

## Structure Order

```typescript
'use client' // Only if using hooks

// Imports (external → internal)
// Constants at module level
const CONFIG = { SPACING: 8 } as const

// Props interface
interface ComponentProps {
requiredProp: string
optionalProp?: boolean
}

export function Component({ requiredProp, optionalProp = false }: ComponentProps) {
// a. Refs
// b. External hooks (useParams, useRouter)
// c. Store hooks
// d. Custom hooks
// e. Local state
// f. useMemo
// g. useCallback
// h. useEffect
// i. Return JSX
}
```

## Rules

1. `'use client'` only when using React hooks
2. Always define props interface
3. Extract constants with `as const`
4. Semantic HTML (`aside`, `nav`, `article`)
5. Optional chain callbacks: `onAction?.(id)`

## Component Extraction

**Extract when:** 50+ lines, used in 2+ files, or has own state/logic

**Keep inline when:** < 10 lines, single use, purely presentational
55 changes: 55 additions & 0 deletions .claude/rules/sim-hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
paths:
- "apps/sim/**/use-*.ts"
- "apps/sim/**/hooks/**/*.ts"
---

# Hook Patterns

## Structure

```typescript
interface UseFeatureProps {
id: string
onSuccess?: (result: Result) => void
}

export function useFeature({ id, onSuccess }: UseFeatureProps) {
// 1. Refs for stable dependencies
const idRef = useRef(id)
const onSuccessRef = useRef(onSuccess)

// 2. State
const [data, setData] = useState<Data | null>(null)
const [isLoading, setIsLoading] = useState(false)

// 3. Sync refs
useEffect(() => {
idRef.current = id
onSuccessRef.current = onSuccess
}, [id, onSuccess])

// 4. Operations (useCallback with empty deps when using refs)
const fetchData = useCallback(async () => {
setIsLoading(true)
try {
const result = await fetch(`/api/${idRef.current}`).then(r => r.json())
setData(result)
onSuccessRef.current?.(result)
} finally {
setIsLoading(false)
}
}, [])

return { data, isLoading, fetchData }
}
```

## Rules

1. Single responsibility per hook
2. Props interface required
3. Refs for stable callback dependencies
4. Wrap returned functions in useCallback
5. Always try/catch async operations
6. Track loading/error states
62 changes: 62 additions & 0 deletions .claude/rules/sim-imports.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
paths:
- "apps/sim/**/*.ts"
- "apps/sim/**/*.tsx"
---

# Import Patterns

## Absolute Imports

**Always use absolute imports.** Never use relative imports.

```typescript
// ✓ Good
import { useWorkflowStore } from '@/stores/workflows/store'
import { Button } from '@/components/ui/button'

// ✗ Bad
import { useWorkflowStore } from '../../../stores/workflows/store'
```

## Barrel Exports

Use barrel exports (`index.ts`) when a folder has 3+ exports. Import from barrel, not individual files.

```typescript
// ✓ Good
import { Dashboard, Sidebar } from '@/app/workspace/[workspaceId]/logs/components'

// ✗ Bad
import { Dashboard } from '@/app/workspace/[workspaceId]/logs/components/dashboard/dashboard'
```

## No Re-exports

Do not re-export from non-barrel files. Import directly from the source.

```typescript
// ✓ Good - import from where it's declared
import { CORE_TRIGGER_TYPES } from '@/stores/logs/filters/types'

// ✗ Bad - re-exporting in utils.ts then importing from there
import { CORE_TRIGGER_TYPES } from '@/app/workspace/.../utils'
```

## Import Order

1. React/core libraries
2. External libraries
3. UI components (`@/components/emcn`, `@/components/ui`)
4. Utilities (`@/lib/...`)
5. Stores (`@/stores/...`)
6. Feature imports
7. CSS imports

## Type Imports

Use `type` keyword for type-only imports:

```typescript
import type { WorkflowLog } from '@/stores/logs/types'
```
Loading