Files
OSGKeyboard/CONTRIBUTING.md
T
rocky 07067ca6c5 feat: initial release v0.1.0
- Custom Keyboard Extension with push-to-talk UI
- iOS 26 SpeechAnalyzer + DictationTranscriber (iOS 18 SF fallback)
- OpenAI-compatible LLM client (4 built-in providers + custom)
- 3-page onboarding flow + provider config UI
- App Group shared storage for cross-process config
- 8s LLM timeout with raw-transcript fallback
- App Store privacy manifests for both targets
- SwiftLint + XcodeGen + GitHub Actions CI
- Unit tests (4/4 passing)
2026-06-17 23:08:58 +08:00

2.7 KiB

Contributing to OSGKeyboard

Thanks for your interest! OSGKeyboard is a small, opinionated iOS app. We welcome bug reports, feature ideas, and pull requests — please read this guide first.

Code of Conduct

This project follows the Contributor Covenant. By participating you agree to its terms.

Filing a bug

Open an issue using the Bug report template. Please include:

  • iOS version + device model
  • Xcode version (run xcodebuild -version)
  • Steps to reproduce
  • Relevant logs (Console.app filtered to OSGKeyboard)

Proposing a feature

Open an issue using the Feature request template. Briefly describe:

  • What problem it solves
  • Your proposed UX / API
  • Any alternatives you considered

Submitting a pull request

  1. Fork & branch. Branch from main with a descriptive name (feat/custom-provider, fix/asr-timeout).
  2. Generate the project locally:
    brew install xcodegen swiftlint
    xcodegen generate
    
  3. Code style. SwiftLint config lives in .swiftlint.yml — keep it green. We use Swift 6 strict concurrency, no Sendable shims where avoidable.
  4. Tests. Add XCTest coverage in OpenLessTests/ for any non-trivial logic.
  5. Build & test before pushing:
    xcodebuild -project OSGKeyboard.xcodeproj \
      -scheme OSGKeyboard \
      -destination 'platform=iOS Simulator,name=iPhone 17' \
      test
    
  6. Commit messages. Short imperative summary (fix: handle empty transcript), longer body if needed.
  7. Open the PR against main. The CI pipeline (.github/workflows/ci.yml) will lint + build + test automatically.

Project structure

OpenLess/          Main iOS app target
OpenLessKeyboard/  Custom Keyboard Extension target
OpenLessShared/    Framework shared by app + extension
OpenLessTests/     XCTest unit tests
project.yml        XcodeGen project definition (source of truth)
.github/workflows/ CI

Adding a new LLM provider

The simplest contribution: add a preset to OpenLessShared/Models/LLMProvider.swift. No other code change is needed — OpenAICompatibleClient handles any OpenAI-compatible endpoint.

Coding conventions

  • Swift 6 strict concurrency
  • @MainActor on any UI-touching type
  • async/await everywhere; no completion-handler chains
  • Public types use PascalCase, internal-only types can use lowerCamelCase
  • File headers use the // FileName.swift// OSGKeyboard · <Target> → blank-line → doc-comment style already in the repo

Releasing

Maintainers cut releases from main via GitHub Releases. The release tag follows vX.Y.Z. CHANGELOG.md is updated as part of the release PR.