# oscarcreatess/airpointer architecture

> Architecture diagram of the GitHub repository oscarcreatess/airpointer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/oscarcreatess/airpointer
- Repository: https://github.com/oscarcreatess/airpointer

## Overview

AirPointer is a macOS app that turns a paired AirPods case into a cursor and tap/gesture controller. The user enables Accessibility, connects and orients the case, calibrates the screen, teaches taps, then toggles a live session with a global shortcut. The graph captures documented setup, pointing, gesture, audio, and helper-program responsibilities. Edges follow shown app/session calls or README-described runtime links; unsampled subsystem relationships are omitted where ownership is unclear.

Main entry points: [`Sources/AirPointer/Session/ClosedCaseSession.swift`](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/ClosedCaseSession.swift) (Closed-case session), [`Sources/AirPointer/App/AppHome.swift`](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/App/AppHome.swift) (Session orchestration), [`Sources/AirPointer/App/AirPointer.swift`](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/App/AirPointer.swift) (App lifecycle), [`Sources/AirPointer/Interface/SetupAssistant.swift`](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/SetupAssistant.swift) (Setup assistant)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["App control"]
  node_app["App lifecycle<br/>[AirPointer.swift]"]
  node_shortcut["Global shortcut"]
  node_orchestration["Session orchestration<br/>[AppHome.swift]"]
end

subgraph group_experience["Setup and interface"]
  node_setup["Setup assistant"]
  node_accessibility["Accessibility guide"]
  node_home["Home and settings"]
  node_menu["Menu bar UI<br/>[StatusBarUI.swift]"]
  node_notch["Notch flow<br/>[NotchFlow.swift]"]
  node_lessons["Case lessons<br/>[CaseLessons.swift]"]
  node_taptest["Tap teaching<br/>[TapTest.swift]"]
end

subgraph group_runtime["Pointer session"]
  node_session["Closed-case session"]
  node_device["AirPods discovery"]
  node_motion["Motion mapping<br/>[Orientation.js]"]
  node_tap["Tap recognition"]
  node_tapinput["Headphone tap input"]
  node_drag["Drag lock<br/>[DragLock.swift]"]
  node_scroll["Twist scrolling<br/>[TwistScroll.swift]"]
  node_slides["Slide control<br/>[SlideControl.swift]"]
  node_cursor["Cursor sizing<br/>[CursorSize.swift]"]
  node_audio["Audio protection"]
end

subgraph group_helpers["Bluetooth helpers"]
  node_restore["Bluetooth restore"]
  node_motionhelper["Motion helper"]
end

node_user(("Mac user"))
node_macos["macOS"]
node_airpods["AirPods case"]
node_macpointer["Cursor and clicks"]

node_user -->|"launches"| node_app
node_user -->|"completes setup"| node_setup
node_setup -->|"requests permission"| node_accessibility
node_user -->|"presses"| node_shortcut
node_app -->|"starts"| node_orchestration
node_orchestration -->|"creates session"| node_session
node_app -->|"shows"| node_home
node_app -->|"shows"| node_setup
node_app -->|"installs"| node_notch
node_shortcut -->|"toggles session"| node_orchestration
node_orchestration -->|"updates state"| node_menu
node_orchestration -->|"updates state"| node_home
node_orchestration -->|"updates state"| node_setup
node_orchestration -->|"opens"| node_taptest
node_session -->|"selects device"| node_device
node_session -->|"runs helper"| node_restore
node_session -.->|"starts sensors"| node_motionhelper
node_motionhelper -.->|"streams motion"| node_session
node_session -.->|"sends heartbeat"| node_motionhelper
node_session -->|"maps motion"| node_motion
node_session -->|"recognizes taps"| node_tap
node_tap -->|"reads input"| node_tapinput
node_session -->|"handles gestures"| node_drag
node_session -.->|"handles rotation"| node_scroll
node_session -->|"dispatches slides"| node_slides
node_session -->|"resizes cursor"| node_cursor
node_session -->|"protects audio"| node_audio
node_motion -->|"provides position"| node_macpointer
node_tap -->|"posts clicks"| node_macpointer
node_macpointer -->|"controls cursor"| node_macos
node_airpods -.->|"supplies motion"| node_motionhelper
node_airpods -.->|"supplies taps"| node_tapinput
node_lessons -.->|"supports guidance"| node_orchestration

click node_app "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/App/AirPointer.swift"
click node_shortcut "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/App/PointerShortcut.swift"
click node_orchestration "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/App/AppHome.swift"
click node_setup "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/SetupAssistant.swift"
click node_accessibility "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/AccessibilityGuide.swift"
click node_home "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/AirPointerHome.swift"
click node_menu "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/StatusBarUI.swift"
click node_notch "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/NotchFlow.swift"
click node_lessons "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/CaseLessons.swift"
click node_taptest "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/TapTest.swift"
click node_session "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/ClosedCaseSession.swift"
click node_device "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/ClosedCaseAirPods.swift"
click node_motion "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/Orientation.js"
click node_tap "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/ClosedCaseTap.swift"
click node_tapinput "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/HeadphoneTapInput.swift"
click node_drag "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/DragLock.swift"
click node_scroll "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/TwistScroll.swift"
click node_slides "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/SlideControl.swift"
click node_cursor "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/CursorSize.swift"
click node_audio "https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/AudioOutputGuard.swift"
click node_restore "https://github.com/oscarcreatess/airpointer/blob/main/Sources/ClosedCaseRestore/ClosedCaseRestore.swift"
click node_motionhelper "https://github.com/oscarcreatess/airpointer/tree/main/Sources/ClosedCaseMotion"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_shortcut,node_orchestration,node_user toneBlue
class node_setup,node_accessibility,node_home,node_menu,node_notch,node_lessons,node_taptest toneAmber
class node_session,node_device,node_motion,node_tap,node_tapinput,node_drag,node_scroll,node_slides,node_cursor,node_audio toneMint
class node_restore,node_motionhelper toneRose
class node_macos,node_airpods,node_macpointer toneIndigo
```

## Components

### App control

- [App lifecycle](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/App/AirPointer.swift): `Sources/AirPointer/App/AirPointer.swift`
- [Global shortcut](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/App/PointerShortcut.swift): `Sources/AirPointer/App/PointerShortcut.swift`
- [Session orchestration](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/App/AppHome.swift): `Sources/AirPointer/App/AppHome.swift`

### Setup and interface

- [Setup assistant](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/SetupAssistant.swift): `Sources/AirPointer/Interface/SetupAssistant.swift`
- [Accessibility guide](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/AccessibilityGuide.swift): `Sources/AirPointer/Interface/AccessibilityGuide.swift`
- [Home and settings](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/AirPointerHome.swift): `Sources/AirPointer/Interface/AirPointerHome.swift`
- [Menu bar UI](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/StatusBarUI.swift): `Sources/AirPointer/Interface/StatusBarUI.swift`
- [Notch flow](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/NotchFlow.swift): `Sources/AirPointer/Interface/NotchFlow.swift`
- [Case lessons](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/CaseLessons.swift): `Sources/AirPointer/Interface/CaseLessons.swift`
- [Tap teaching](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Interface/TapTest.swift): `Sources/AirPointer/Interface/TapTest.swift`

### Pointer session

- [Closed-case session](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/ClosedCaseSession.swift): `Sources/AirPointer/Session/ClosedCaseSession.swift`
- [AirPods discovery](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/ClosedCaseAirPods.swift): `Sources/AirPointer/Session/ClosedCaseAirPods.swift`
- [Motion mapping](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/Orientation.js): `Sources/AirPointer/Session/Orientation.js`
- [Tap recognition](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/ClosedCaseTap.swift): `Sources/AirPointer/Session/ClosedCaseTap.swift`
- [Headphone tap input](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/HeadphoneTapInput.swift): `Sources/AirPointer/Session/HeadphoneTapInput.swift`
- [Drag lock](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/DragLock.swift): `Sources/AirPointer/Session/DragLock.swift`
- [Twist scrolling](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/TwistScroll.swift): `Sources/AirPointer/Session/TwistScroll.swift`
- [Slide control](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/SlideControl.swift): `Sources/AirPointer/Session/SlideControl.swift`
- [Cursor sizing](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/CursorSize.swift): `Sources/AirPointer/Session/CursorSize.swift`
- [Audio protection](https://github.com/oscarcreatess/airpointer/blob/main/Sources/AirPointer/Session/AudioOutputGuard.swift): `Sources/AirPointer/Session/AudioOutputGuard.swift`

### Bluetooth helpers

- [Bluetooth restore](https://github.com/oscarcreatess/airpointer/blob/main/Sources/ClosedCaseRestore/ClosedCaseRestore.swift): `Sources/ClosedCaseRestore/ClosedCaseRestore.swift`
- [Motion helper](https://github.com/oscarcreatess/airpointer/tree/main/Sources/ClosedCaseMotion): `Sources/ClosedCaseMotion`

### Other components

- **Mac user**
- **macOS**
- **AirPods case**
- **Cursor and clicks**

## Connections

- Mac user → App lifecycle: launches (evidence: `README.md`)
- Mac user → Setup assistant: completes setup (evidence: `README.md`)
- Setup assistant → Accessibility guide: requests permission (evidence: `Sources/AirPointer/Interface/SetupAssistant.swift`)
- Mac user → Global shortcut: presses (evidence: `README.md`)
- App lifecycle → Session orchestration: starts (evidence: `Sources/AirPointer/App/AirPointer.swift`)
- Session orchestration → Closed-case session: creates session (evidence: `Sources/AirPointer/App/AppHome.swift`)
- App lifecycle → Home and settings: shows (evidence: `Sources/AirPointer/App/AirPointer.swift`)
- App lifecycle → Setup assistant: shows (evidence: `Sources/AirPointer/App/AirPointer.swift`)
- App lifecycle → Notch flow: installs (evidence: `Sources/AirPointer/App/AirPointer.swift`)
- Global shortcut → Session orchestration: toggles session (evidence: `Sources/AirPointer/App/AppHome.swift`)
- Session orchestration → Menu bar UI: updates state (evidence: `Sources/AirPointer/App/AppHome.swift`)
- Session orchestration → Home and settings: updates state (evidence: `Sources/AirPointer/App/AppHome.swift`)
- Session orchestration → Setup assistant: updates state (evidence: `Sources/AirPointer/App/AppHome.swift`)
- Session orchestration → Tap teaching: opens
- Closed-case session → AirPods discovery: selects device (evidence: `Sources/AirPointer/Session/ClosedCaseSession.swift`)
- Closed-case session → Bluetooth restore: runs helper (evidence: `Sources/AirPointer/Session/ClosedCaseSession.swift`)
- Closed-case session → Motion helper: starts sensors (evidence: `README.md`)
- Motion helper → Closed-case session: streams motion (evidence: `README.md`)
- Closed-case session → Motion helper: sends heartbeat (evidence: `README.md`)
- Closed-case session → Motion mapping: maps motion (evidence: `README.md`)
- Closed-case session → Tap recognition: recognizes taps (evidence: `Sources/AirPointer/Session/ClosedCaseSession.swift`)
- Tap recognition → Headphone tap input: reads input (evidence: `Sources/AirPointer/Session/ClosedCaseTap.swift`)
- Closed-case session → Drag lock: handles gestures (evidence: `Sources/AirPointer/Session/ClosedCaseSession.swift`)
- Closed-case session → Twist scrolling: handles rotation
- Closed-case session → Slide control: dispatches slides (evidence: `Sources/AirPointer/Session/ClosedCaseSession.swift`)
- Closed-case session → Cursor sizing: resizes cursor (evidence: `Sources/AirPointer/Session/ClosedCaseSession.swift`)
- Closed-case session → Audio protection: protects audio (evidence: `Sources/AirPointer/Session/ClosedCaseSession.swift`)
- Motion mapping → Cursor and clicks: provides position (evidence: `README.md`)
- Tap recognition → Cursor and clicks: posts clicks (evidence: `README.md`)
- Cursor and clicks → macOS: controls cursor (evidence: `README.md`)
- AirPods case → Motion helper: supplies motion (evidence: `README.md`)
- AirPods case → Headphone tap input: supplies taps
- Case lessons → Session orchestration: supports guidance
