Thank you for your interest in contributing to PulseRT! This document provides guidelines and instructions for contributing.
- Report bugs - Found something broken? Let us know
- Suggest features - Have an idea? We'd love to hear it
- Submit pull requests - Code contributions are welcome
- Improve documentation - Help make the docs clearer
- Share feedback - Tell us about your experience
Before reporting a bug, please:
- Search existing issues to avoid duplicates
- Try the latest version to see if it's already fixed
When reporting, include:
- macOS version
- PulseRT version or commit hash
- Steps to reproduce
- Expected vs actual behavior
- Any error messages (check Console.app for logs)
- Screenshots if relevant
Open an issue with:
- Clear description of the feature
- Use case - why is this useful?
- Any implementation ideas (optional)
- macOS 26 or later
- Xcode 16+
- Git
-
Fork the repository on GitHub
-
Clone your fork:
git clone https://github.com/YOUR_USERNAME/pulsert.git cd pulsert -
Open in Xcode:
open PulseRT.xcodeproj
-
Set up test credentials (optional, for integration testing):
mkdir -p ~/.config/pulsert cp credentials.example.json ~/.config/pulsert/credentials.json # Edit with your actual service account credentials
-
Build and run with Cmd+R
PulseRT/
├── Models/ # Data structures
├── ViewModels/ # SwiftUI view models
├── Views/ # SwiftUI views
├── Services/ # Business logic, API clients
├── Utilities/ # Helpers (JWT signing, etc.)
└── Resources/ # Assets, Info.plist
- Follow Swift API Design Guidelines
- Use Swift 6.0 features where appropriate
- Prefer
letovervarwhen possible - Use meaningful variable and function names
- Keep functions focused and concise
- Use Xcode's default formatting (Ctrl+I to re-indent)
- 4 spaces for indentation
- Opening braces on the same line
- One blank line between functions
- Remove trailing whitespace
- Add doc comments (
///) for public APIs - Include parameter descriptions for non-obvious parameters
- Document any side effects or preconditions
/// Fetches the current active user count from Google Analytics.
///
/// - Parameter propertyId: The GA4 property ID (numeric).
/// - Returns: The number of active users, or 0 if unavailable.
/// - Throws: `AnalyticsError` if the API request fails.
func fetchActiveUsers(propertyId: String) async throws -> Int {
// Implementation
}-
Create a branch from
main:git checkout -b feature/your-feature-name
-
Make your changes:
- Keep commits focused and atomic
- Write clear commit messages
- Test your changes thoroughly
-
Push to your fork:
git push origin feature/your-feature-name
-
Open a Pull Request:
- Provide a clear title and description
- Reference any related issues
- Include screenshots for UI changes
- List any breaking changes
-
Respond to feedback:
- Address review comments
- Push additional commits as needed
- Keep the PR updated with
mainif needed
- Use present tense: "Add feature" not "Added feature"
- Use imperative mood: "Fix bug" not "Fixes bug"
- Keep the first line under 72 characters
- Add details in the body if needed
Good examples:
Add refresh interval picker to settings
Fix token refresh not triggering before expiry
Update README with troubleshooting section
- Test manually on macOS 26
- Verify menu bar appearance and behavior
- Test settings persistence across app restarts
- Check error handling with invalid credentials
- Test network error recovery
- Never commit real credentials
- Don't log sensitive information (tokens, keys)
- Validate all user input
- See SECURITY.md for more details
- Be respectful and inclusive
- Assume good intent
- Focus on constructive feedback
- Welcome newcomers
Open an issue with the "question" label or reach out to the maintainers.
Thank you for contributing to PulseRT!