Transcripted is a local Mac app that turns meetings and dictation into structured voice artifacts people and agents can both use.
Quick repo orientation before you jump in:
mainis the current Transcripted product built from the Draft codebase- the old standalone Transcripted app is preserved on
legacy/transcripted-standaloneandpre-draft-takeover-2026-04-06 - persisted app paths now default to Transcripted-named storage, though some helper names and standalone-tool fallbacks still reflect the Draft transition
- coding agents should start with
AGENT_START.md, then followAGENTS.md
In public docs and user-facing copy, prefer concrete present-tense claims about what the product does today. The broader "audio as a context layer" thesis is real, but it should be earned through proof rather than stated as if the future state already exists.
- macOS 26+
- Xcode command line tools
- Apple Silicon
-
Fork the repo and clone your fork:
git clone https://github.com/YOUR_USERNAME/transcripted.git cd transcripted -
Build dependencies and the app:
bash build-deps.sh bash build.sh --no-open
-
Run the test suite:
bash run-tests.sh
If you touch meeting integration or TranscriptedCore, also run:
bash run-integration-smoke.shOn first launch, models may download from HuggingFace if they are not already cached locally.
Build note: build.sh is the authoritative app build and uses raw swiftc.
Package.swift exists for TranscriptedCore compilation and testing, but it
is not the main app build.
For the current script surface and legacy helpers, see scripts/README.md.
For the active repo map and directory responsibilities, see docs/repo-layout.md.
For the path-to-verification map used by agents, see .agents/test-matrix.yml
or run:
scripts/dev/agent-preflight.shWhen you change README copy, onboarding text, or public docs, keep these rules in mind:
- lead with the concrete product: local dictation and local meeting capture
- treat "agent-ready artifacts" as a present-tense capability
- treat "ambient context layer" as vision language, not current product language
- be precise about what stays local and what may still contact external services
- explain legacy
Draftpaths as compatibility behavior, not as a second product
Create a branch from main with a descriptive name:
feat/description
fix/description
docs/description
refactor/description
- Follow existing Swift conventions in the codebase
- Use
// MARK:comments to organize sections within files - Never do I/O, locks, or allocations inside CoreAudio real-time callbacks
- Keep
@MainActorannotations correct
The codebase is organized around the current Transcripted app:
| Area | Directory | Responsibility |
|---|---|---|
| App entry + state | Sources/ |
app lifecycle, hotkeys, paths, shared state |
| Dictation capture and storage | Sources/Speech/, Sources/Dictation/, Sources/Capture/ |
speech capture, trigger routing, saved dictation transcripts |
| Meeting pipeline | Sources/Meeting/ |
meeting recording, model warmup, transcript flow |
| UI | Sources/UI/ |
grouped app surfaces: Overlay/, MenuBar/, Settings/, Shared/ |
| Shared meeting core | Sources/TranscriptedCore/ |
extracted meeting/transcription library and agent artifacts |
Some internal folders still use Draft naming while the repo and product are
being aligned publicly around Transcripted. Treat those as implementation
details unless a change specifically affects compatibility paths.
For the canonical root and directory map, see docs/repo-layout.md.
Transcripted prefers durable local outputs over opaque app-only state.
That means changes should preserve or improve:
- readable Markdown outputs
- structured JSON sidecars and indexes
- stable storage paths
- the ability for external agents to consume saved artifacts directly
Transcripted has strict threading rules due to CoreAudio's real-time requirements:
| Component | Thread | Notes |
|---|---|---|
| Session controllers + UI state | @MainActor |
UI-bound state |
| Audio capture internals | DispatchQueue + NSLock |
Real-time audio I/O |
| CoreAudio I/O callbacks | real-time thread | No I/O, locks, allocations, or ObjC calls |
CoreAudio I/O callbacks run on real-time threads. Buffers are deep-copied before async dispatch, never processed in-place.
Run the default test suite from the command line:
bash run-tests.shIf you're changing meeting integration or TranscriptedCore, also run:
bash run-integration-smoke.shrun-tests.sh discovers root fast tests by convention. A new
Tests/FooTests.swift file must expose exactly one top-level testFoo() entry.
Update run-tests.sh only when the compiled source list or runner behavior changes.
- Make sure your code builds without warnings
- Run the relevant test suite
- Keep PRs focused, one feature or fix per PR
- Explain both what changed and why it matters
- Call out privacy, storage-path, or migration implications when relevant
- Link any related issues
Open a GitHub issue with:
- macOS version
- steps to reproduce
- expected vs actual behavior
- whether the issue affects dictation, meetings, or agent artifacts
- relevant logs from
~/Library/Application Support/Transcripted/logs/events.jsonlor~/Library/Application Support/Transcripted/logs/debug.log
If your machine uses a custom capture library or you are reproducing against legacy Draft-era artifacts, mention that in the report.
Open a GitHub issue for questions or discussion.