diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 3c280dfc32..72b5c7264e 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -25,7 +25,7 @@ amethyst/ **Sharing Philosophy:** - `quartz/` = Business logic, protocol, data (no UI) -- `commons/` = Shared UI components, icons, composables +- `commons/` = Shared UI components, icons, composables, **ViewModels** - `amethyst/` & `desktopApp/` = Platform-native layouts and navigation ## Tech Stack @@ -123,8 +123,8 @@ When picking up a new task or feature, follow this process: 3. **Key principle:** Most logic already exists! Your job is to: - **Reuse** existing protocol/business logic from quartz - - **Extract** shareable UI components from amethyst to commons - - Create **platform-specific** ViewModels/navigation for Desktop + - **Extract** shareable UI components AND ViewModels from amethyst to commons + - Create **platform-specific** layouts/navigation for Desktop - **NOT** duplicate existing managers, caches, or state systems 4. **Document findings in implementation plan as a matrix:** @@ -133,7 +133,7 @@ When picking up a new task or feature, follow this process: |----------------|--------|----------|--------| | FilterBuilders | ✅ Exists | quartz/relay/filters/ | Reuse as-is | | NoteCard | 📦 Extract | amethyst/ui/note/ → commons/ | Extract to commons | - | HomeFeedViewModel | 🆕 New | Create in desktopApp/ | Create for Desktop | + | HomeFeedViewModel | 📦 Extract | amethyst/ → commons/commonMain/viewmodels/ | Extract to commons | | ProfileCache | ⚠️ Avoid | N/A | Already in User/Account pattern | **Legend:** @@ -156,24 +156,26 @@ Before coding, create a plan that categorizes work into three buckets: | Category | Description | Location | |----------|-------------|----------| -| **Android-Specific** | Platform APIs, navigation, layouts | `amethyst/`, `androidMain/` | -| **Reusable (Shared)** | Business logic, UI components, state | `quartz/commonMain/`, `commons/` (convert to KMP) | -| **Desktop-Specific** | Desktop navigation, layouts, platform APIs | `desktopApp/`, `jvmMain/` | +| **Android-Specific** | Platform-native layouts, navigation patterns | `amethyst/`, `androidMain/` | +| **Reusable (Shared)** | Business logic, UI components, **ViewModels**, state management | `quartz/commonMain/`, `commons/commonMain/` | +| **Desktop-Specific** | Desktop-native layouts, navigation patterns, platform APIs | `desktopApp/`, `jvmMain/` | ### Step 3: Code Sharing Strategy **Share:** - Business logic and data models → `quartz/commonMain/` -- Major UI components (cards, lists, dialogs) → `commons/` (convert to KMP as needed) -- State management and ViewModels → shared +- Major UI components (cards, lists, dialogs) → `commons/commonMain/` +- **ViewModels** (state, business logic) → `commons/commonMain/viewmodels/` - Icons and visual assets → `commons/commonMain/` **Keep Platform-Native:** +- **Screen composables** (layout, scaffolding) - Desktop uses `Window`, Android uses `Activity` - Navigation patterns (sidebar vs bottom nav) -- Screen layouts and scaffolding - Platform-specific interactions (gestures, keyboard shortcuts) - System integrations (notifications, file pickers) +**Rationale:** ViewModels contain platform-agnostic state management (StateFlow/SharedFlow) and business logic. Screens consume ViewModels but render differently (Desktop sidebar + content area vs Android bottom nav). + ### Step 4: Extract Shared Components When extracting UI components: diff --git a/.claude/skills/kotlin-multiplatform/SKILL.md b/.claude/skills/kotlin-multiplatform/SKILL.md index 13df020fde..b0aa2f8d6d 100644 --- a/.claude/skills/kotlin-multiplatform/SKILL.md +++ b/.claude/skills/kotlin-multiplatform/SKILL.md @@ -182,12 +182,13 @@ Quick decision guidelines based on codebase patterns: ### Sometimes Abstract - **Business logic:** YES - state machines, data processing -- **UI state:** NO - ViewModels platform-specific -- **Why:** Separate concerns, business logic reusable +- **ViewModels:** YES - state + business logic shareable (StateFlow/SharedFlow) +- **Screen layouts:** NO - platform-native (Window vs Activity) +- **Why:** ViewModels contain platform-agnostic state; Screens render differently per platform ### Rarely Abstract -- **UI components** (composables with platform dependencies) -- **Why:** Platform paradigms differ (bottom nav vs sidebar) +- **Complex UI components** (composables with heavy platform dependencies) +- **Why:** Platform paradigms can differ significantly ### Never Abstract - **Navigation** (Activity vs Window fundamentally different) @@ -201,8 +202,8 @@ Quick decision guidelines based on codebase patterns: |-----------|---------|-----------| | PubKeyFormatter, ZapFormatter | ✅ YES | Pure Kotlin, no platform APIs | | TimeAgoFormatter | ⚠️ ABSTRACTED | Needs StringProvider for localized strings | -| Navigation (INav) | ❌ NO | Activity vs Window too different | -| AccountViewModel | ⚠️ PARTIAL | Business logic → IAccountState (shared), UI state → platform ViewModels | +| ViewModels (state + logic) | ✅ YES | StateFlow/SharedFlow platform-agnostic, Compose Multiplatform lifecycle compatible | +| Screen layouts (Scaffold, nav) | ❌ NO | Window vs Activity, sidebar vs bottom nav fundamentally different | | Image loading (Coil) | ⚠️ ABSTRACTED | Coil 3.x supports KMP, needs expect/actual wrapper | ## expect/actual Mechanics @@ -380,9 +381,10 @@ import com.fasterxml.jackson.databind.ObjectMapper | Crypto (varies by platform) | expect in commonMain, actual in platforms | Different security APIs per platform | | I/O, logging | expect in commonMain, actual in platforms | Platform implementations differ | | State (business logic) | commonMain or commons/jvmAndroid | Reusable StateFlow patterns | -| State (UI) | Platform ViewModels | Platform-specific lifecycle | +| **ViewModels** | **commons/commonMain/viewmodels/** | **StateFlow/SharedFlow + logic shareable, Compose MP lifecycle compatible** | | UI formatters (pure) | commons/commonMain | Reusable, no dependencies | -| UI components (complex) | Platform-specific | Paradigms differ | +| UI components (simple) | commons/commonMain | Cards, buttons, dialogs | +| **Screen layouts** | **Platform-specific** | **Window vs Activity, sidebar vs bottom nav** | | Navigation | Platform-specific only | Activity vs Window too different | | Permissions | Platform-specific only | APIs incompatible | | Platform UX (menus, etc.) | Platform-specific only | Native feel required |