Thanks for your interest in contributing to Poirot! Here's how to get started.
- macOS 15.0+
- Xcode 16.0+
Install SwiftLint and SwiftFormat via Homebrew:
brew install swiftlint swiftformatgit clone https://github.com/LeonardoCardoso/Poirot.git
cd Poirot
brew install swiftlint swiftformat
open Poirot.xcodeprojBuild with Cmd+B in Xcode, or from the command line:
xcodebuild -scheme Poirot -destination 'platform=macOS' -skipMacroValidation buildRun the full test suite:
xcodebuild test -scheme Poirot -destination 'platform=macOS' -skipMacroValidationTests use Swift Testing (@Test, #expect, #require). We do not use XCTest for new tests.
- Swift 6 with
MainActordefault isolation — all types are implicitly@MainActor - SwiftLint runs automatically during build (see
.swiftlint.yml) - SwiftFormat for formatting (see
.swiftformat) - Use
nonisolatedonly for file I/O or heavy computation - New service protocols get hand-written mocks in
PoirotTests/Mocks/
Poirot/Sources/
├── App/ # App entry point, ContentView, AppState
├── Models/ # Value-type structs (Project, Session, Message)
├── Protocols/ # Service protocols
├── Services/ # Concrete implementations + Environment DI
├── Theme/ # Design tokens (PoirotTheme)
└── Views/ # SwiftUI views organized by feature
- Models — Plain structs,
Sendableby default - Services — Protocol-first with
EnvironmentValuesinjection - State —
@Observablewith@State(notObservableObject) - Icons — SF Symbols only, with symbol effects for stateful icons
- Fork the repo and create a feature branch from
main - Make your changes with tests
- Ensure build passes with zero warnings
- Ensure all tests pass
- Ensure SwiftLint passes
- Open a PR against
main