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:
    1. The problem being solved
    2. Why the current behavior is insufficient
    3. 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 coordinators
  • Cotabby/UI/: SwiftUI presentation and menu/settings surfaces
  • Cotabby/Services/: OS integrations, async work, permissions, and runtime boundaries
  • Cotabby/Models/: shared value types, state snapshots, and protocol contracts
  • Cotabby/Support/: pure rules, prompt helpers, normalization, and low-level utilities

If you are changing behavior, prefer this order:

  1. Pure logic in Support/
  2. Side-effectful boundaries in Services/
  3. Orchestration in App/
  4. 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:

  1. Select the Cotabby scheme.
  2. Choose your Mac as the run destination.
  3. Build and run.
  4. Complete onboarding.
  5. Grant Accessibility and Input Monitoring when prompted.
  6. 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 #N or Refs #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: xcodebuild compile 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.