Thank you for your interest in contributing to RClick! 🎉
RClick is a macOS Finder enhancement tool built with Swift 6.2 and SwiftUI. This guide will help you get set up and make your first contribution.
- Code of Conduct
- Getting Started
- Development Workflow
- Coding Guidelines
- Testing
- Finding Issues to Work On
This project follows the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to the project maintainers.
| Tool | Version |
|---|---|
| macOS | 15.6 (Sequoia) or later |
| Xcode | 16.4 or later |
| Swift | 6.2 or later |
# Clone the repository
git clone https://github.com/wflixu/RClick.git
cd RClick
# Open in Xcode
open RClick.xcodeproj
# Or build from CLI
xcodebuild -project RClick.xcodeproj -scheme RClick -destination 'platform=macOS'Note: The FinderSync Extension requires code signing. When building for development, Xcode will automatically use your development team. You may need to adjust the signing settings in Signing & Capabilities.
RClick/
├── RClick/ # Main application target
│ ├── RClickApp.swift # App entry point
│ ├── AppState.swift # Global state management
│ ├── Model/ # SwiftData models
│ ├── Settings/ # Settings UI (SwiftUI)
│ ├── Shared/ # Utilities & services
│ └── Assets.xcassets/ # Images, icons, templates
├── FinderSyncExt/ # Finder extension target
│ ├── FinderSyncExt.swift # Extension entry point
│ └── MenuItemClickable.swift # Menu item handlers
└── specs/ # Feature specifications & contracts
main— Production-ready releases. Always stable.dev— Integration branch. All feature branches merge here first.- Feature branches —
feature/your-feature-nameorfix/your-bug-fix
# Start new feature
git checkout dev
git pull origin dev
git checkout -b feature/my-new-feature
# Start a bug fix
git checkout -b fix/my-bug-fixWe follow Conventional Commits. Please structure your commit messages as:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types:
| Type | Usage |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation changes |
refactor |
Code refactoring (no feature/fix) |
perf |
Performance improvement |
test |
Adding or updating tests |
chore |
Build, CI, dependencies |
style |
Formatting, whitespace |
Examples:
feat(settings): add dark mode toggle to general settings
fix(finder): resolve menu item not appearing on first launch
docs: update README with installation guide
refactor(ipc): simplify messaging layer with async/await
- Fork the repository and create your branch from
dev. - Implement your changes, following the coding guidelines below.
- Test your changes thoroughly (build, run, verify in Finder).
- Update documentation if your changes affect user-facing behavior.
- Submit a PR targeting the
devbranch. - Fill out the PR template — describe what changed, why, and how to test.
- Wait for review — a maintainer will review your PR. CI checks must pass.
PR titles should also follow Conventional Commits, e.g., feat: add AirDrop sharing support.
- Use Swift 6.2 syntax — no legacy patterns.
- Prefer
letovervarwhere possible. - Use
async/awaitfor concurrency. Avoid completion handlers. - Use
@MainActorwhen updating@Publishedproperties from background contexts. - Mark types and methods with appropriate access control (
private,internal). - Use
guardfor early returns, not nestedifstatements. - Prefer value types (
struct,enum) over reference types when identity isn't needed.
- All UI must be SwiftUI — no AppKit UI components (e.g., no
NSViewRepresentablewrappers for visual elements). - AppKit is ONLY for system integration:
NSWorkspace,NSPasteboard, file operations, etc. - Use
@StateObjectfor view-ownedObservableObjectinstances; use@ObservedObjectfor injected ones. - Keep views small and composable. Extract reusable components.
- Use SF Symbols for icons to ensure native look and dark mode support.
These are hard constraints from the project constitution:
- Swift 6.2 syntax only — no older Swift patterns.
- SwiftUI for all UI — no AppKit UI components.
- AppKit limited to system integration —
NSWorkspace,NSPasteboard, file operations, etc. - Target macOS 15 Sequoia and above only — no backward compatibility hacks.
Dual-Process Communication:
- Main app and FinderSync Extension communicate via
DistributedNotificationCenter. - Message protocol is defined in
RClick/Shared/Messager.swift. - Always handle
isHostAppOpenstate — don't block if the main app isn't running.
Before submitting a PR, please verify:
# Build the main app
xcodebuild -project RClick.xcodeproj -scheme RClick -destination 'platform=macOS'
# Build the extension
xcodebuild -project RClick.xcodeproj -scheme FinderSyncExt -destination 'platform=macOS'
# Run tests (if applicable)
xcodebuild test -project RClick.xcodeproj -scheme RClick -destination 'platform=macOS'Manual testing checklist:
- App launches and appears in the menu bar
- Right-click menu appears in Finder with all configured items
- Dark mode works correctly (icons adapt)
- Settings persist across app restarts
- File operations work (create, delete, copy path, etc.)
- Extension loads after system restart
- Browse open issues — look for
good first issueorhelp wantedlabels. - If you have an idea, open a discussion first to get feedback before writing code.
Thank you for contributing! 🚀