Files
yattee/AGENTS.md
2026-02-08 18:33:56 +01:00

3.1 KiB

Yattee Development Guide for AI Agents

Deployment Targets

iOS: 18.0+ | macOS: 15.0+ | tvOS: 18.0+

This project targets the latest OS versions only - use newest APIs freely without availability checks.

Build & Test Commands

Build: xcodebuild -scheme Yattee -configuration Debug
Test (all): xcodebuild test -scheme Yattee -destination 'platform=macOS'
Test (single): xcodebuild test -scheme Yattee -destination 'platform=macOS' -only-testing:YatteeTests/TestSuiteName/testMethodName
Lint: periphery scan (config: .periphery.yml)

Code Style

Language: Swift 5.0+ with strict concurrency (Swift 6 mode enabled)
UI: SwiftUI with @Observable macro for view models (not ObservableObject)
Concurrency: Use actor for services, @MainActor for UI-related code, async/await everywhere
Testing: Swift Testing framework (@Test, @Suite, #expect) - NOT XCTest

Imports & Organization

Import order: Foundation first, then SwiftUI, then @testable imports
File headers: Include // FileName.swift, // Yattee, and brief comment describing purpose
MARK comments: Use // MARK: - Section Name to organize code sections
Sendable: All models, errors, and actors must conform to Sendable

Types & Naming

Models: Immutable structs with Codable, Hashable, Sendable conformance
Services: Use actor for thread-safe services, final class for @Observable view models
Enums: Use associated values for typed errors (see APIError.swift)
Optionals: Prefer guard-let unwrapping; use if let for simple cases
Naming: camelCase for variables/functions, PascalCase for types, clear descriptive names

Error Handling

Errors: Define typed enum errors conforming to Error, LocalizedError, Equatable, Sendable
Async throws: All async network/IO operations should throw typed errors
Logging: Use LoggingService.shared for all logging (see HTTPClient.swift for patterns)
User feedback: Provide localized error descriptions via errorDescription

Testing & Debugging

Add logging/visual clues (borders, backgrounds) when debugging issues - then ask user for results
If first fix doesn't work: Add debug code before second attempt to understand the issue better

UI Testing (Ruby/RSpec with AXe CLI)

Run UI tests: ./bin/ui-test --skip-build --keep-simulator
Run single spec: SKIP_BUILD=1 KEEP_SIMULATOR=1 bundle exec rspec spec/ui/smoke/search_spec.rb

Accessibility labels vs identifiers: On iOS 26+, .accessibilityIdentifier() doesn't work reliably on Group, ScrollView, and some container views (AXUniqueId comes back empty). Use .accessibilityLabel() instead, which maps to AXLabel and can be detected via AXe's text_visible?() method.

iOS 26 TabView search: The search field is integrated into the bottom tab bar with Tab(role: .search). Typing \n doesn't submit - use hardware key press via press_return (AXe key 40).

ScrollView children: Video rows inside LazyVStack/ScrollView aren't exposed in the accessibility tree. Use coordinate-based tapping instead.