Contributing To Cotabby
June 5, 2026 · View on GitHub
Thanks for helping improve Cotabby. This guide is the contributor entry point for local setup, validation, and codebase orientation.
Cotabby is a macOS menu bar app that provides on-device inline autocomplete in other apps. The repo is split by responsibility so contributors can make small, reviewable changes without spreading platform-specific behavior across unrelated layers.
Please read and follow the Code of Conduct before participating.
Before You Start
- Read README.md for the product overview and end-user setup.
- Read ARCHITECTURE.md before changing the suggestion pipeline, runtime lifecycle, or Accessibility behavior.
- Check for an existing issue or open one before starting substantial work.
- Prefer small, atomic PRs with a single clear objective. Large mixed-purpose changes are harder to review, validate, and revert safely.
- Before implementing a change, make sure you can clearly explain:
- The problem being solved
- Why the current behavior is insufficient
- Why the proposed approach fits the existing architecture
Development Prerequisites
You need:
- macOS 14.0 or later for running the app and tests. Apple Intelligence runtime work requires macOS 26 or later.
- Xcode with Command Line Tools installed.
- A local Apple development team configured in Xcode if you want to launch the signed app from the IDE.
- SwiftLint for local lint checks. CI installs it with Homebrew when needed.
- XcodeGen if you need to change the project structure (targets, build settings, dependencies,
or scheme). Install it with
brew install xcodegen. CI installs it the same way.
Apple Silicon is strongly recommended for local model-runtime work.
Local Setup
Clone the repo and open the project:
git clone https://github.com/FuJacob/Cotabby.git
cd Cotabby
open Cotabby.xcodeproj
In Xcode, select the Cotabby scheme. If you run from Xcode, set your signing team under
Signing & Capabilities.
The Xcode Project Is Generated
Cotabby.xcodeproj is generated from project.yml by XcodeGen.
It is committed to the repo so you can clone and open Cotabby.xcodeproj without any extra tooling,
but project.yml is the source of truth.
Source files under Cotabby/ and CotabbyTests/ are auto-discovered by folder, so adding a new
file (including a new test) needs no project edit — just create it and regenerate. Only structural
changes (targets, build settings, package dependencies, scheme) require editing project.yml.
After any structural change, regenerate and commit the result:
xcodegen generate
CI runs the XcodeGen workflow on every PR and fails if the committed Cotabby.xcodeproj differs
from what project.yml produces. If that check is red, run xcodegen generate and commit the diff.
Avoid hand-editing the project in Xcode without mirroring the change into project.yml.
How To Navigate The Repo
Start with these boundaries:
Cotabby/App/: app lifecycle, composition root, and top-level coordinatorsCotabby/UI/: SwiftUI presentation and menu/settings surfacesCotabby/Services/: OS integrations, async work, permissions, and runtime boundariesCotabby/Models/: shared value types, state snapshots, and protocol contractsCotabby/Support/: pure rules, prompt helpers, normalization, and low-level utilities
If you are changing behavior, prefer this order:
- Pure logic in
Support/ - Side-effectful boundaries in
Services/ - Orchestration in
App/ - Presentation in
UI/
That separation keeps behavior easier to test and reduces regressions in Accessibility-heavy code.
Build
For a local compile check:
xcodebuild \
-project Cotabby.xcodeproj \
-scheme Cotabby \
-configuration Debug \
-destination 'platform=macOS' \
CODE_SIGNING_ALLOWED=NO \
build
CODE_SIGNING_ALLOWED=NO keeps the build command usable on machines that do not have the project
owner's signing certificate. Use Xcode with your own team selected when you need to launch the app
locally.
Run
From Xcode:
- Select the
Cotabbyscheme. - Choose your Mac as the run destination.
- Build and run.
- Complete onboarding.
- Grant Accessibility and Input Monitoring when prompted.
- Pick Apple Intelligence if available, or use the Open Source engine with a downloaded GGUF model.
If a suggestion does not appear or the overlay is misplaced, start with the focus and geometry sections in ARCHITECTURE.md before changing coordinator logic.
Test
Run the unit test suite:
xcodebuild test \
-project Cotabby.xcodeproj \
-scheme Cotabby \
-destination 'platform=macOS' \
CODE_SIGNING_ALLOWED=NO
The CI test workflow uses the same macOS deployment target as the app, so tests should not require a macOS 26 runner unless a future change raises the app baseline again.
Lint
Run SwiftLint locally:
swiftlint --reporter github-actions-logging
The current CI lint gate is warnings-only. Treat warnings as cleanup work, but avoid bundling unrelated style rewrites into functional PRs.
Debugging
The shared Xcode scheme passes -cotabby-debug by default in Debug builds. This enables
developer-only diagnostics:
- Focus debug overlay: translucent panels showing caret geometry, element bounds, focus polling events, and visual-context pipeline status.
- Suggestion debug logger: color-coded console output for each generation cycle: prompt sent, raw model response, and normalized output.
- Screenshot capture: saves OCR debug screenshots to disk when the visual-context pipeline runs.
To disable it, uncheck -cotabby-debug in the scheme's Run → Arguments tab.
Pull Requests
Before opening or updating a PR:
- Keep the change scoped to one problem.
- Explain what changed and why.
- Link the relevant issue with
Fixes #NorRefs #N. - Include screenshots or short recordings for visible UI changes.
- Run the relevant validation command for your change:
- build for compile-only or docs-adjacent changes
- tests for logic or pipeline behavior
- SwiftLint for style-sensitive edits
- Call out skipped validation explicitly.
- Keep unrelated refactors out of the PR.
- Update docs when setup, release flow, permissions, architecture, or user-facing behavior changes.
Use the repository PR template and replace every placeholder section with concrete content grounded in the actual diff and validation output.
CI Expectations
PRs into main run:
- Build:
xcodebuildcompile check - Tests:
xcodebuild test - Lint: SwiftLint warnings surfaced as GitHub annotations
If CI fails because of your change, fix the root cause in the same PR. If the failure is unrelated infrastructure noise, note that clearly in the PR description.