Building from source
Building from source
Lettuce is a SwiftPM project. The source is available via private repo invite during the 0.x series and goes open-source (MIT) at 1.0 — repo: github.com/DrBaher/lettuce.
Pre-requisites
macOS 14 (Sonoma) or later
Xcode 16+ installed (for the SDK; you won’t open Xcode itself)
Apple Silicon recommended; Intel works but slower
Clone
git clone https://github.com/DrBaher/lettuce.git
cd lettuce
Build
There’s intentionally no .xcodeproj — everything is SwiftPM. The repo’s main entry point is ./Scripts/run.sh:
./Scripts/run.sh
This:
Sets
DEVELOPER_DIR=/Applications/Xcode.app/Contents/DeveloperRuns
swift build -c debugBundles the result into a runnable
.appLaunches it
For a release build:
./Scripts/run.sh --release
For headless (no app launch — useful in CI):
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift build -c release
Run the CLI
After a build:
.build/arm64-apple-macosx/release/Lettuce --help
Or use the run.sh shortcut:
./Scripts/run.sh --cli docs path
Run tests
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer swift test
This takes ~30 seconds for the full suite. To run a subset:
swift test --filter DocsVault
swift test --filter SuggestionsModeTests
Build the QuickLook plugin
The .qlgenerator is built by a separate script because SwiftPM doesn’t know about .appex bundles:
./Scripts/build-quicklook.sh
Output: .build/Lettuce.qlgenerator/. To install for testing:
./Scripts/install-quicklook.sh
qlmanage -r
Package for distribution
The full release flow (build, sign, notarise, bundle DMG, deploy site):
./Scripts/package.sh --version 0.6.1
You’ll need:
Developer ID Application certificate in Keychain
Notarisation credential profile named
lettuce-notary(set up viaxcrun notarytool store-credentials)
This script is also the spec for what the CI does — read it for the canonical flow.
Toolchain pinning
Lettuce pins to Swift 6.0 (with language mode 5 for transitions). The toolchain comes from Xcode (whatever version is at DEVELOPER_DIR). To use a different one:
xcode-select -p # current
sudo xcode-select -s /path/to/Xcode-16.4.app
Common gotchas
“DEVELOPER_DIR” required
SwiftPM needs Xcode’s SDK. Set:
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
Add to ~/.zshrc to make permanent.
Build fails with “missing required module”
A package dependency didn’t resolve. Try:
swift package resolve
swift package update
“Bundle.module” returns nil at runtime
You added a resource file but didn’t tell SwiftPM. Add to the target’s resources: list in Package.swift:
resources: [.process("Resources"), .copy("Docs")],
.process is for files SwiftPM should handle (xib, strings, …); .copy is for arbitrary files (especially when you need subdirectory structure preserved — see For developers/04 Architecture map).
Tests fail with “fatal error: nil”
Usually a missing resource. Run swift build first, check .build/.../Lettuce_LettuceKit.bundle/ for expected files.