From 3dcb7225c4459d003171edf726c48abe858dc83d Mon Sep 17 00:00:00 2001 From: Ross Nelson Date: Wed, 24 Sep 2025 15:56:18 -0400 Subject: [PATCH] docs: improve CLAUDE.md contributing guide - Add critical lint/check section at top - Highlight key patterns and must-follow rules - Add common mistakes section - Make guide more scannable and actionable - Add PR checklist and references to codebase - Remove verbose explanations for clarity --- .gitignore | 2 +- .serena/memories/code_style_conventions.md | 133 +++++++++++++++ .serena/memories/holocene_design_system.md | 112 +++++++++++++ .serena/memories/project_overview.md | 42 +++++ .serena/memories/project_structure.md | 85 ++++++++++ .serena/memories/suggested_commands.md | 97 +++++++++++ .serena/memories/task_completion_checklist.md | 117 ++++++++++++++ CLAUDE.md | 153 +++++++++++------- 8 files changed, 680 insertions(+), 61 deletions(-) create mode 100644 .serena/memories/code_style_conventions.md create mode 100644 .serena/memories/holocene_design_system.md create mode 100644 .serena/memories/project_overview.md create mode 100644 .serena/memories/project_structure.md create mode 100644 .serena/memories/suggested_commands.md create mode 100644 .serena/memories/task_completion_checklist.md diff --git a/.gitignore b/.gitignore index 38809f2cf7..ed3adacc47 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,4 @@ server/ui/assets /audits go.work go.work.sum -.claude +.claude/settings.local.json diff --git a/.serena/memories/code_style_conventions.md b/.serena/memories/code_style_conventions.md new file mode 100644 index 0000000000..6b85c447bc --- /dev/null +++ b/.serena/memories/code_style_conventions.md @@ -0,0 +1,133 @@ +# Code Style and Conventions + +## Svelte 5 Patterns + +### Props Definition + +```typescript +interface Props { + class?: string; + adapter: Adapter; +} +let { class: className = '', adapter }: Props = $props(); +``` + +### State Management + +```typescript +// State +let count = $state(0); + +// Computed values +const doubled = $derived(count * 2); + +// Complex computed with function +const complex = $derived.by(() => { + // computation logic + return result; +}); + +// Effects (use sparingly - team prefers avoiding them) +$effect.pre(() => { + // side effect logic +}); +``` + +### SuperForms Pattern + +```typescript +const { form, errors, enhance } = $derived( + superForm(data, { + SPA: true, + validators: zodClient(schema), + onUpdate: async ({ form }) => { + // handle submit + }, + }), +); +``` + +## Import Order (STRICT) + +1. Node.js built-ins +2. External libraries (`svelte/**` first) +3. SvelteKit imports (`$app/**`, `$types`) +4. Internal imports (`$lib/**`) +5. Component imports (`$components/**/*.svelte`) +6. Relative imports (`./`, `../`) + +## Naming Conventions + +- **Files**: kebab-case (`workflow-status.svelte`) +- **Components**: PascalCase in imports, kebab-case files +- **Functions**: camelCase +- **Types/Interfaces**: PascalCase +- **Constants**: UPPER_SNAKE_CASE or PascalCase +- **CSS classes**: kebab-case with Tailwind utilities + +## TypeScript Requirements + +- Always use proper types (no `any`, `unknown`, or `as` assertions) +- Use `import type` for type-only imports +- Prefer interfaces over type aliases for object shapes +- Use generic constraints instead of type escapes + +## Functional Programming Patterns + +- **Guard statements**: Use early returns, no nested if/else +- **Pure functions**: No side effects in transformations +- **Immutable patterns**: Don't mutate inputs +- **Small functions**: Single responsibility +- **Explicit errors**: Throw meaningful errors, don't fail silently +- **Constants over functions**: `const VALUE = x` not `const getValue = () => x` +- **Logical operators**: Use `||` for fallbacks, not if statements + +## Component Structure + +``` +component-name/ +├── index.svelte # Main component +├── {name}.ts # Pure functions, types +├── {name}.svelte.ts # Svelte lifecycle functions +└── {sub}.svelte # Sub-components +``` + +## Formatting Rules (Prettier) + +- Print width: 80 +- Tab width: 2 spaces +- Single quotes +- Semicolons: always +- Trailing comma: all +- Bracket spacing: true + +## CSS/Styling + +- Use TailwindCSS utilities first +- PostCSS for custom styles +- Holocene design system components +- Avoid inline styles +- Use CSS variables from theme + +## Comments and Documentation + +- NO code comments unless explicitly requested +- Use descriptive variable/function names instead +- TypeScript types serve as documentation +- Component props should be self-documenting + +## Error Handling + +- Use Zod for validation +- Handle errors at component level +- Show user-friendly error messages +- Use toast notifications for async operations +- Implement proper loading states + +## Accessibility + +- Semantic HTML elements +- Proper ARIA attributes +- Keyboard navigation support +- Screen reader compatibility +- Color contrast compliance diff --git a/.serena/memories/holocene_design_system.md b/.serena/memories/holocene_design_system.md new file mode 100644 index 0000000000..5b806ede30 --- /dev/null +++ b/.serena/memories/holocene_design_system.md @@ -0,0 +1,112 @@ +# Holocene Design System + +## Overview + +Holocene is Temporal UI's custom design system built with Svelte 5 and TailwindCSS. It provides a consistent set of components following Temporal's design language. + +## Core Components + +### Layout Components + +- **Card**: Content container with optional header/footer +- **Panel**: Side panel for additional content +- **Modal**: Overlay dialogs +- **Accordion**: Collapsible content sections +- **Tabs**: Tabbed navigation +- **VerticalNav**: Vertical navigation with animated backgrounds + +### Form Components + +- **Input**: Text input with validation +- **Select**: Dropdown selection +- **Checkbox**: Boolean selection +- **Radio**: Single choice selection +- **Toggle**: On/off switch +- **DatePicker**: Date selection +- **Combobox**: Searchable dropdown + +### Data Display + +- **Table**: Data tables with sorting/filtering +- **DataTable**: Advanced table with pagination +- **CodeBlock**: Syntax-highlighted code display +- **Badge**: Status indicators +- **Chip**: Tag/label display +- **EmptyState**: No data states + +### Navigation + +- **Button**: Primary interactive element +- **Link**: Navigation links +- **Breadcrumb**: Navigation hierarchy +- **Pagination**: Page navigation +- **TabList/TabPanel**: Tab navigation + +### Feedback + +- **Alert**: Information messages +- **Toast**: Temporary notifications +- **Loading**: Loading indicators +- **Skeleton**: Content placeholders +- **Tooltip**: Contextual help + +## Component Structure + +```typescript +// Standard component pattern + + +
+ +
+``` + +## Design Tokens + +- Colors: Uses Tailwind color palette +- Spacing: 4px base unit (0.5, 1, 2, 4, 8, etc.) +- Typography: System font stack +- Shadows: Tailwind shadow utilities +- Borders: 1px default, rounded corners + +## Best Practices + +1. Always use Holocene components when available +2. Follow existing component patterns +3. Use TailwindCSS utilities for styling +4. Maintain consistent spacing +5. Ensure keyboard accessibility +6. Include ARIA attributes +7. Support dark/light themes +8. Test in Storybook + +## Creating New Components + +1. Place in `src/lib/holocene/component-name/` +2. Export from `index.svelte` +3. Add Storybook story +4. Follow naming conventions +5. Include TypeScript types +6. Support standard HTML attributes +7. Use `twMerge` for class merging + +## Common Utilities + +- `twMerge`: Merge Tailwind classes +- `formatDate`: Date formatting +- `translate`: i18n translations +- `getContext/setContext`: Component communication +- `createEventDispatcher`: Custom events diff --git a/.serena/memories/project_overview.md b/.serena/memories/project_overview.md new file mode 100644 index 0000000000..92d3ed1f32 --- /dev/null +++ b/.serena/memories/project_overview.md @@ -0,0 +1,42 @@ +# Temporal UI Project Overview + +## Purpose + +Temporal UI is a web-based interface for the Temporal workflow orchestration platform. It provides a visual interface for managing and monitoring Temporal workflows, activities, namespaces, and other Temporal resources. + +## Tech Stack + +- **Framework**: SvelteKit with Svelte 5 +- **Language**: TypeScript +- **Styling**: TailwindCSS + PostCSS +- **Design System**: Holocene (custom component library) +- **Build Tool**: Vite +- **Package Manager**: pnpm (>=8.6.0) +- **Node Version**: >=18.15.0 +- **Testing**: Vitest (unit), Playwright (e2e/integration), Storybook (components) +- **Code Quality**: ESLint, Prettier, Stylelint, svelte-check +- **Forms**: SuperForms with Zod validation +- **State Management**: Svelte stores and runes + +## Key Features + +- Workflow execution monitoring and management +- Namespace management +- Search attributes configuration +- Activity tracking +- Real-time updates +- Multi-language support (i18n) + +## Development Modes + +- `dev`: Local development with UI server +- `dev:temporal-cli`: Development with Temporal CLI +- `dev:docker`: Development against Docker Compose Temporal +- `dev:local-temporal`: Development with local Temporal server + +## Architecture + +- Server-side rendering with SvelteKit +- Type-safe API calls using generated TypeScript types +- Responsive design with mobile support +- Modular component architecture using Holocene design system diff --git a/.serena/memories/project_structure.md b/.serena/memories/project_structure.md new file mode 100644 index 0000000000..8830860c12 --- /dev/null +++ b/.serena/memories/project_structure.md @@ -0,0 +1,85 @@ +# Temporal UI Project Structure + +## Root Directory + +``` +/Users/ross/code/ui/ +├── src/ # Source code +├── tests/ # E2E and integration tests +├── static/ # Static assets +├── server/ # UI server build output +├── build/ # Build output +├── dist/ # Distribution files +├── node_modules/ # Dependencies +├── .storybook/ # Storybook configuration +├── scripts/ # Build and utility scripts +├── temporal/ # Temporal API protos (git submodule) +└── docs/ # Documentation + +## Source Structure +src/ +├── app.css # Global styles +├── app.html # HTML template +├── app.d.ts # Global TypeScript types +├── hooks.server.ts # SvelteKit server hooks +├── lib/ # Library code +│ ├── components/ # Reusable components +│ ├── holocene/ # Design system components +│ ├── services/ # API and business logic +│ ├── stores/ # Svelte stores +│ ├── types/ # TypeScript type definitions +│ ├── utilities/ # Helper functions +│ ├── i18n/ # Internationalization +│ ├── theme/ # Theme configuration +│ └── vendor/ # Third-party integrations +├── routes/ # SvelteKit routes +│ ├── (app)/ # Main app routes +│ ├── (auth)/ # Auth-related routes +│ └── api/ # API routes +└── fixtures/ # Test fixtures + +## Key Directories + +### Holocene Design System +src/lib/holocene/ +- Alert, Button, Card, Modal components +- Form controls (Input, Select, Checkbox) +- Navigation (Tabs, VerticalNav) +- Data display (Table, CodeBlock) +- Layout components + +### Routes Organization +src/routes/(app)/ +├── namespaces/ # Namespace management +├── workflows/ # Workflow listing and details +├── schedules/ # Schedule management +├── batch-operations/ # Batch operations +└── nexus/ # Nexus endpoints + +### Component Patterns +- Route-specific: `routes/.../\_components/` +- Reusable: `lib/components/` +- Design system: `lib/holocene/` + +## Configuration Files +- `vite.config.ts` - Vite configuration +- `svelte.config.js` - SvelteKit configuration +- `tailwind.config.ts` - TailwindCSS configuration +- `tsconfig.json` - TypeScript configuration +- `.env.*` - Environment configurations +- `playwright.config.ts` - E2E test configuration +- `vitest.config.ts` - Unit test configuration + +## Build Outputs +- `dist/` - Local build output +- `server/ui/assets/` - UI server assets +- `.svelte-kit/` - SvelteKit build cache +- `build/` - Production build + +## Important Files +- `CLAUDE.md` - AI assistant instructions +- `package.json` - Dependencies and scripts +- `.prettierrc` - Code formatting rules +- `.eslintrc.cjs` - Linting rules +- `.stylelintrc` - CSS linting rules +``` diff --git a/.serena/memories/suggested_commands.md b/.serena/memories/suggested_commands.md new file mode 100644 index 0000000000..d783739278 --- /dev/null +++ b/.serena/memories/suggested_commands.md @@ -0,0 +1,97 @@ +# Suggested Commands for Temporal UI Development + +## Essential Development Commands + +### Starting Development + +```bash +pnpm dev # Start dev server with UI server (default) +pnpm dev:temporal-cli # Dev with Temporal CLI +pnpm dev:docker # Dev against Docker Compose +pnpm dev:local-temporal # Dev with local Temporal server +``` + +### Code Quality (MUST RUN AFTER CHANGES) + +```bash +pnpm lint # Run all linters (prettier, eslint, stylelint) +pnpm check # TypeScript type checking +pnpm format # Auto-fix all formatting issues +``` + +### Individual Linters + +```bash +pnpm prettier # Check code formatting +pnpm prettier:fix # Auto-fix formatting +pnpm eslint # Check ESLint rules +pnpm eslint:fix # Auto-fix ESLint issues +pnpm stylelint # Check CSS/PostCSS styles +pnpm stylelint:fix # Auto-fix style issues +``` + +### Testing + +```bash +pnpm test # Run unit tests +pnpm test:ui # Run tests with UI +pnpm test:coverage # Run tests with coverage +pnpm test:e2e # Run end-to-end tests +pnpm test:integration # Run integration tests +``` + +### Building + +```bash +pnpm build:local # Build for local preview +pnpm build:server # Build for UI server +pnpm build:docker # Build for Docker +pnpm preview:local # Preview built app +``` + +### Storybook + +```bash +pnpm stories:dev # Start Storybook dev server +pnpm stories:build # Build Storybook +pnpm stories:test # Test Storybook stories +``` + +### Git Commands (Darwin/macOS) + +```bash +git status # Check current changes +git add -A # Stage all changes +git commit -m "message" # Commit with message +git push # Push to remote +git stash # Stash current changes +git stash pop # Apply stashed changes +``` + +### System Utilities (Darwin/macOS) + +```bash +ls -la # List files with details +find . -name "*.ts" # Find TypeScript files +grep -r "pattern" . # Search for pattern +open . # Open current directory in Finder +pbcopy < file # Copy file to clipboard +pbpaste > file # Paste clipboard to file +``` + +### Package Management + +```bash +pnpm install # Install dependencies +pnpm add package # Add new dependency +pnpm add -D package # Add dev dependency +pnpm update # Update dependencies +``` + +## Important Notes + +- Always run `pnpm lint` and `pnpm check` before committing +- Use `pnpm format` to auto-fix most issues +- The project uses pnpm, not npm or yarn +- Node version must be >=18.15.0 +- pnpm version must be >=8.6.0 diff --git a/.serena/memories/task_completion_checklist.md b/.serena/memories/task_completion_checklist.md new file mode 100644 index 0000000000..413333114a --- /dev/null +++ b/.serena/memories/task_completion_checklist.md @@ -0,0 +1,117 @@ +# Task Completion Checklist + +## MUST DO After Every Code Change + +### 1. Run Linting (REQUIRED) + +```bash +pnpm lint +``` + +This runs prettier, eslint, and stylelint. Fix any issues before proceeding. + +### 2. Run Type Checking (REQUIRED) + +```bash +pnpm check +``` + +Ensures TypeScript types are correct. Must pass without errors. + +### 3. Auto-fix Issues (if needed) + +```bash +pnpm format +``` + +Automatically fixes most formatting and linting issues. + +### 4. Run Tests (for logic changes) + +```bash +pnpm test -- --run # Run unit tests +pnpm test:e2e # Run e2e tests if UI changed +``` + +### 5. Test in Browser + +- Start dev server: `pnpm dev` +- Test the feature/fix manually +- Check console for errors +- Verify responsive behavior + +### 6. Check Storybook (for component changes) + +```bash +pnpm stories:dev +``` + +Update or add stories for new/modified components. + +## Before Committing + +### Git Workflow + +1. Stage changes: `git add -A` +2. Review changes: `git status` and `git diff --staged` +3. Commit with conventional format: + ```bash + git commit -m "type(scope): description" + ``` + Types: feat, fix, docs, style, refactor, test, chore + +### PR Checklist + +- [ ] Linting passes (`pnpm lint`) +- [ ] Type checking passes (`pnpm check`) +- [ ] Tests pass (if applicable) +- [ ] Manual testing completed +- [ ] No console errors +- [ ] Responsive design verified +- [ ] Accessibility checked (keyboard nav, ARIA) +- [ ] No hardcoded strings (use i18n) +- [ ] Follows team conventions + +## Common Issues to Check + +### Import Order + +Verify imports follow the strict order: + +1. Node built-ins +2. External libraries +3. SvelteKit imports +4. Internal imports +5. Component imports +6. Relative imports + +### Type Safety + +- No `any` types +- No `as` type assertions +- No `@ts-ignore` comments +- Proper type imports with `import type` + +### Code Style + +- Guard statements (early returns) +- No nested if/else blocks +- Pure functions where possible +- Descriptive variable names +- No unnecessary comments + +### Performance + +- Lazy loading for heavy components +- Proper use of `$derived` vs `$effect` +- No memory leaks in effects +- Efficient list rendering with keys + +## Final Verification + +```bash +# Run all checks at once +pnpm lint && pnpm check && pnpm test -- --run +``` + +If all pass, the code is ready for review! diff --git a/CLAUDE.md b/CLAUDE.md index e96847edf5..bd5312b46f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,82 +1,115 @@ -# Claude AI Assistant Rules for Temporal UI +# Temporal UI - Contributing Guide -SvelteKit + Svelte 5 + TypeScript + TailwindCSS + Holocene design system +**Stack**: SvelteKit + Svelte 5 + TypeScript + TailwindCSS + Holocene design system -## Commands +## 🚨 CRITICAL: After Every Change ```bash -pnpm lint # Run all linters -pnpm check # TypeScript type checking -pnpm test -- --run # Run unit tests +pnpm lint # MUST PASS - fixes formatting, eslint, stylelint +pnpm check # MUST PASS - TypeScript type checking ``` -## Svelte 5 Patterns +## 🎯 Key Patterns + +### Svelte 5 Runes (NO class components) ```typescript -// Props -let { class: className = '', adapter }: Props = $props(); +let { class: className = '', ...props }: Props = $props(); // Props +let count = $state(0); // State +const doubled = $derived(count * 2); // Computed +$effect(() => { + /* use sparingly - team dislikes */ +}); // Effects +``` -// State -let count = $state(0); +### Component Structure -// Computed -const doubled = $derived(count * 2); +``` +component-name/ +├── index.svelte # Main component +├── {name}.ts # Pure functions, types +└── {name}.svelte.ts # Svelte lifecycle functions +``` -// Effects -$effect(() => { - console.log('Count:', count); - return () => cleanup(); -}); - -// SuperForms -const { form, errors, enhance } = $derived( - superForm(data, { - SPA: true, - validators: zodClient(schema), - onUpdate: async ({ form }) => { - /* handle submit */ - }, - }), -); +### Import Order (STRICT - linter enforces) + +1. Node built-ins +2. External (`svelte/**` first) +3. SvelteKit (`$app/**`, `$types`) +4. Internal (`$lib/**`) +5. Components (`*.svelte`) +6. Relative (`./`, `../`) + +## ⚡ Development Commands + +```bash +# Development +pnpm dev # Start dev server (default) +pnpm dev:temporal-cli # With Temporal CLI + +# Testing +pnpm test -- --run # Unit tests +pnpm test:e2e # E2E tests (if UI changed) +pnpm stories:dev # Storybook for components + +# Auto-fix most issues +pnpm format ``` -## Import Order +## 📝 Code Style + +### MUST Follow -1. Node.js built-ins -2. External libraries (with `svelte/**` first) -3. SvelteKit imports (`$app/**`, `$types`) -4. Internal imports (`$lib/**`) -5. Component imports (`$components/**/*.svelte`) -6. Relative imports (`./`, `../`) +- **NO `any` types** - use proper types or generics +- **NO nested if/else** - use guard statements with early returns +- **NO comments** unless explicitly requested +- **USE Holocene components** - check `src/lib/holocene/` first +- **USE functional patterns** - pure functions, immutable data -## Workflow +### Naming -1. **Always run linting**: Execute `pnpm lint` after making changes -2. **Type checking**: Run `pnpm check` to verify TypeScript compliance -3. **Test execution**: Run appropriate test suites based on changes -4. **Follow patterns**: Use existing component patterns and utility functions -5. **Design system**: Prefer Holocene components over custom implementations -6. **Accessibility**: Ensure proper ARIA attributes and semantic HTML +- Files: `kebab-case.svelte` +- Components: `PascalCase` in imports +- Functions: `camelCase` +- Types: `PascalCase` +- CSS: Tailwind utilities first + +## 🏗️ Project Structure + +``` +src/ +├── routes/(app)/ # Main app routes +│ └── _components/ # Route-specific components +├── lib/ +│ ├── holocene/ # Design system (USE THESE!) +│ ├── components/ # Shared components +│ ├── services/ # API calls +│ └── utilities/ # Helpers +``` -## Code Generation +## ✅ PR Checklist -- **No comments**: Don't add code comments unless explicitly requested -- **Type safety**: Always provide proper TypeScript types -- **Component reuse**: Leverage existing components and utilities -- **Test coverage**: Write tests for new utilities and business logic -- **Import organization**: Follow the established import order +- [ ] `pnpm lint` passes +- [ ] `pnpm check` passes +- [ ] Manual testing completed +- [ ] Responsive design verified +- [ ] Used Holocene components where available +- [ ] No hardcoded strings (use i18n) +- [ ] Follows functional patterns (guard statements, no nested if/else) -## Error Handling +## 🔗 References -- **Validation**: Use Zod for runtime type validation -- **Error boundaries**: Implement proper error boundaries for components -- **Network errors**: Handle API failures gracefully -- **User feedback**: Provide clear error messages and loading states +- [Holocene Components](src/lib/holocene/) - Design system +- [Component Examples](src/lib/holocene/**/*.stories.svelte) - Storybook stories +- [Route Patterns]() - Route organization +- [Form Patterns]() - SuperForms with Zod -## Naming +## 🚫 Common Mistakes -- **Files**: kebab-case (`workflow-status.svelte`) -- **Components**: PascalCase in imports, kebab-case for files -- **Functions**: camelCase -- **Types**: PascalCase -- **Use** `import type` for type-only imports +1. Using `any` type → Use proper types +2. Creating custom components → Check Holocene first +3. Nested if/else → Use early returns +4. Forgetting to lint → Always run `pnpm lint` +5. Wrong import order → Follow the strict order +6. Adding comments → Code should be self-documenting +7. Using `$effect` → Team prefers `$derived`