Rules were created for each topic with Perplexity and o3
- Opus 4 is the best for large changes, unmatched in architecture and understanding
- Sonnet 4 is good for precise edits
- Gemini 2.5 Pro for a middle path
- Haven't tried o3 yet
- Create a folder in your project's root
.cursor/rules - Add each rulefile inside
rulesas<rule>.mdc - Set all to
Always Onfor best adherence (Agent Requested doesn't really work imo) - Install the extensions
Sweetpad&xcbeautifyfrom here Cursor Docs iOS
For my dev setup this works well. You might want to adjust it to yours.
---
description:
globs:
alwaysApply: true
---
### Rule: Navigating Stubborn Swift Build & Linter Errors
- **Trust the Build, Not the Linter:** The linter can be wrong, especially with Swift package dependencies. If a user reports a successful build that contradicts the linter, trust the build. Do not get stuck in a loop trying to fix linter errors that the compiler does not report.
- **Minimal Incremental Changes:** When facing persistent build failures that are hard to diagnose, take the smallest possible step. Make one logical change, then stop and wait for a build confirmation. This is the most reliable way to isolate the exact point of failure.
- **Challenge API Assumptions:** If a type or method from an external library cannot be found after 2-3 attempts, even if it seems correct based on documentation, assume your understanding of the library's API is flawed. The actual type might have a different name or be accessed in a different way (e.g., `EVEvent` instead of `EventSource.Event.Received`).
- **Consult External Analysis:** When stuck on a problem like this, do not continue to repeat the same failed strategy. You should use external analysis tools (like Search and Devin) to get a different perspective, as they may have a more accurate or up-to-date understanding of the library's structure.
- **Don't Build** Don't try to build the project, ask the user ALWAYS to build and test.
---
type: Always On
description: Simple MVVM + Repository architecture for a SwiftUI multiplatform (iOS & macOS) app, with a Shared-and-Platform folder layout and conditional-compilation tips.
---
# Folder Structure (Multiplatform)
- **Shared/** — code used by all platforms
- Models/
- Repositories/
- ViewModels/
- Views/SharedComponents/
- Networking/
- **Platforms/**
- **iOSApp/** — iOS launch file (`AICompanion_iOS.swift`), iOS-only assets, push-notification helpers
- **macOSApp/** — macOS launch file (`AICompanion_macOS.swift`), menu-bar extras, window-menu commands
- **Resources/** — localization files, design tokens, color assets common to every target
# MVVM Conventions
- Views are stateless renderers.
- ViewModels (`*ViewModel.swift`) are `@MainActor` classes with `@Published` state and dependencies injected via initializers.
- Repositories expose protocols ending in `Repository` and are isolated from SwiftUI.
# Repository Pattern
- Protocols in `Shared/Repositories/`; concrete implementations in platform folders if required.
- Repositories may call Core Data / SwiftData or `NetworkClient`, but never reference SwiftUI.
# Conditional Compilation & Availability
- Use `#if os(iOS)` / `#if os(macOS)` to gate platform-specific code.
- Decorate newer APIs with `@available(macOS 14, *)` when they shipped later on macOS.
# Keychain & App Group Sharing
- Define a shared App Group ID (`group.com.example.aicompanion`) for file and UserDefaults sharing.
- Enable Keychain Sharing with the same access group in each target’s capabilities.
# Testing Targets
- **AICompanionSharedTests** for unit tests covering ViewModels and Repositories.
- **AICompanion_iOS_UITests** and **AICompanion_macOS_UITests** for platform-specific UI flows.
---
type: Always On
description: SwiftUI coding standards covering view composition, state flow, navigation, accessibility, testing, performance, and concurrency for the AI-Companion app.
---
# Swift Language Guidelines
- Target **Swift 5.10** (Xcode 15.4+) and compile with `-strict-concurrency=complete`.
- Opt-in to concurrency safety; use `@Sendable`, `@MainActor`, and
`nonisolated(unsafe)` only when strictly required.
- Follow Apple’s API Design Guidelines for naming clarity.
# SwiftUI ⇄ SwiftData Basics
- Prefer **SwiftData** (`@Model`, `@Query`) on iOS 17+. Share one
`ModelContainer` at app launch and inject via `.modelContainer(_:)`.
- SwiftData autosaves; call `try context.save()` only if autosave is disabled.
- Use `@StateObject` for long-lived view models and `@ObservedObject`
for short-lived children.
# Core Data Guidelines (legacy & multi-user)
- Use `NSPersistentCloudKitContainer` for iOS 16 support or when you need
multi-user sharing or advanced batch operations.
- Enable lightweight migrations; bump the model version instead of mutating.
- Perform heavy work on background contexts; merge via
`NSManagedObjectContextDidSave`.
# CloudKit Compatibility (MANDATORY)
- Disallow unique constraints, ordered relationships, and “Deny” delete rules.
- All attributes must be optional *or* supply a default value.
- Relationships must be optional, have inverses, and be unordered.
- Apply add-only migrations once the model ships: never delete or rename
entities or attributes.
# CloudKit Sync Implementation
- Enable the iCloud capability and default container in Xcode settings.
- When using raw CKRecord APIs, archive metadata with
`encodeSystemFields(with:)`.
- Show sync status in-app; back off on network and quota errors.
# SwiftData vs Core Data Decision
- **SwiftData**: iOS 17+, single-user CloudKit, minimal boilerplate,
less threading overhead.
- **Core Data**: iOS 16-, multi-user sharing, fine-grained batch operations,
proven scale.
# Concurrency and Actors
- Wrap persistence services in dedicated ModelActors or mark them
`@MainActor`.
- Pass identifiers or DTO structs across actor boundaries—`@Model`
instances are not `Sendable`.
# Security and Encryption
- Encrypt sensitive blobs with CryptoKit AES.GCM; store keys in Keychain /
Secure Enclave.
- Use `@Attribute(.encrypt)` on SwiftData properties for field-level protection.
- Never log plaintext user data.
# Performance
- Paginate large fetches with `FetchDescriptor` or `NSFetchRequest` limits.
- Index frequently filtered properties with `#Index` (SwiftData) or
fetch indexes (Core Data).
- Use batch insert/update APIs for imports and migrations.
# Modern App Architecture
- MVVM plus a Repository layer that hides persistence details.
- Inject dependencies via protocols for testability.
- A dedicated `SyncCoordinator` handles CloudKit state and publishes
Combine updates to the UI.
# Error Handling and Recovery
- Wrap saves in `do / try / catch`; surface user-readable errors.
- Detect iCloud account removal; fall back to local-only mode with a prompt.
# Testing
- Unit-test repositories with `ModelContainer(inMemory:)`.
- UI-test sync flows on two simulators signed into different iCloud accounts.
- Mock CloudKit in unit tests to avoid flaky network failures.
---
type: Always On
description: >
Async/await networking for a forwarding-proxy LLM app (iOS 18+ / macOS 15+):
shared client, JSON encoding/decoding, status-code validation, retries,
ATS, optional pinning, and streaming.
---
# Shared Network Client
- File: `Shared/Networking/URLSessionNetworkClient.swift`
- One protocol-based client reused by all platforms; pure async/await.
## Protocol
public protocol NetworkClient {
func send<Response: Decodable>(
_ request: URLRequest
) async throws -> Response
func send<Body: Encodable, Response: Decodable>(
_ request: URLRequest,
body: Body
) async throws -> Response
}
---
type: Always On
description: SwiftUI coding standards covering view composition, state flow, navigation, accessibility, testing, performance, and concurrency for the AI-Companion app.
---
# SwiftUI Fundamentals
- Compose UIs from small, stateless views; prefer `View` extensions for modifiers.
- Group related modifiers with custom view extensions for reuse and clarity.
- Use stacks, grids, and `Spacer` for adaptive layout; fall back to `GeometryReader` only for edge cases.
# State and Data Flow
- `@State` for simple value types local to a view.
- `@Binding` to share a single source of truth with children.
- `@StateObject` for long-lived reference-type view-models; `@ObservedObject` for transient objects.
- Pass environment data with `@Environment` (theme, locale, colorScheme) and `@EnvironmentObject` for global models.
# Navigation
- Prefer `NavigationStack` and `NavigationPath` for deep linking and state restoration.
- Use `navigationDestination` over multiple nested `NavigationLink`s.
- Keep destination construction lazy to reduce upfront work.
# Concurrency and Tasks
- Mark UI work `@MainActor`; run I/O or CPU-heavy work in detached `Task`.
- Cancel in-flight tasks in `onDisappear` or when model changes.
- Pass value types or identifiers across actor boundaries—reference types must be `Sendable`.
# Accessibility and Localization
- Support Dynamic Type with `font(.body)` and layout that adapts to larger sizes.
- Provide `accessibilityLabel`, `accessibilityHint`, and `accessibilityValue` where needed.
- Keep strings in `Localizable.strings`; prefer `LocalizedStringKey` in SwiftUI.
# Testing and Previews
- Use `#Preview` (or `struct PreviewProvider`) to cover light/dark mode, Dynamic Type, and right-to-left layouts.
- Snapshot UI tests with `XCTAssert` attachments or third-party libraries (e.g. iOSSnapshotTestCase).
- Run XCUITests for navigation flows and accessibility focus order.
# Performance
- Inspect with the SwiftUI Instrument; watch for excessive view invalidations.
- Defer heavy work until first appearance with `.task`.
- Prefer `@Layout` debugging tools and Instruments for slow layouts.
# Architecture and Patterns
- MVVM: View-Model owns state and business logic; View is a pure renderer.
- Repository pattern hides persistence or networking details behind protocols.
- Use dependency injection (constructor or `@Environment`) for easy mocking.
# Error Handling
- Surface recoverable errors with `alert` or `sheet`; log non-fatal errors.
- Wrap async calls in `Task` cancellation checks and user-presentable error types.