Skip to content

Architecture

ScribeKit is Swift and SwiftUI, built on Apple platform frameworks. A dependency is added only when the platform genuinely cannot do the job.

Source layout

ScribeKit/
  App/                    App entry point
  Capture/                Application source discovery and audio capture
  Features/History/       SwiftUI history screen and its state
  Features/MeetingSetup/  SwiftUI configuration screen and its state
  Features/MenuBar/       Menu bar item and the state it presents
  History/                Reading past sessions back, and searching them
  Meeting/                The application-scoped active meeting and its runtime
  Models/                 Domain value types (no I/O)
  Persistence/            Save-location storage and session layout policy
  Transcription/          On-device speech recognition behind its own boundary
ScribeKitTests/           Swift Testing unit tests

The shape of it

flowchart LR
  SCK[ScreenCaptureKit] --> CAP[AudioCapturing]
  CAP --> BC[Broadcasting consumer]
  BC --> TX[SpeechTranscribing]
  BC --> AR[AudioRetaining]
  TX --> RT[MeetingRuntime]
  RT --> TP[TranscriptPersisting]
  TP --> MD[transcript.md]
  AR --> AUD[audio.caf / audio.m4a]
  RT --> UI[Window and menu bar]

Domain models are plain value types with no capture, transcription or persistence behaviour. Session lifecycle is a single MeetingState enum with explicit transition rules, so contradictory states are unrepresentable.

Capture, speech, persistence and session coordination are separate layers behind that model. Source discovery sits behind CaptureSourceProviding, capture behind AudioCapturing, recognition behind SpeechTranscribing, and ScreenCaptureKit and Speech types are adapted at those boundaries rather than reaching the UI — so behaviour stays testable without system permission.

Save-location storage sits behind SaveLocationPersisting, so security-scoped bookmark data never reaches the setup screen, and session directory naming is a pure policy separate from any filesystem work.

Ownership

The active meeting is owned by MeetingRuntime, created by the application delegate and handed to both the window and the menu bar. Its lifetime is the application's. What the setup screen owns is the configuration for the next meeting; the running one holds a MeetingSnapshot taken when it started. See Meeting Lifecycle.

Both interfaces read one derived MeetingRuntimeStatus rather than tracking the meeting separately, so the window and the menu bar cannot disagree.

Reading versus writing

HistoryStoring is a read-only filesystem boundary with no method that creates, replaces, appends to or deletes anything. TranscriptDocument reads a written transcript back into its header fields and finalised spans, HistoryService decides what counts as a meeting, and TranscriptSearch is a pure matcher over what a load produced.

Recovery keeps its own store, because recording an interruption is a write and History never writes. See Architecture Boundaries.