Build
You need Xcode (free, from the App Store) for its toolchain; the Xcode app itself never has to open.
Edit anything under
Sources/Glassine/ and run ./build.sh --run; incremental builds take a few seconds. Opening Package.swift in Xcode and pressing Run works for debugging, but the assembled app from build.sh is the one to use day to day — it has the icon and a stable identity for macOS permissions.
The minimum deployment target is macOS 14. It is developed on macOS 26 and 27 with Xcode 26.
Layout
Two flavors
./build.sh --appstore compiles with APPSTORE set, which turns on the App Sandbox, gives the app its own iCloud container instead of direct access to iCloud Drive, remembers chosen folders with security-scoped bookmarks, and leaves out the GitHub update check. Support/Distribution.swift is where the differences are decided at run time. RELEASING.md in the repository has the whole pipeline for both — certificates, notarization, the store package.
Debugging
Help → Copy Debug Info (⌘⌥⇧D) snapshots the caret’s geometry, the text view’s frame and insets, and every setting, ready to paste into an issue. The app can also photograph itself: launched with-glassine.shoot name.png and a few companion arguments (see Support/ScreenshotMode.swift), it opens at a fixed size with the settings, view and caret position you name, waits for layout, asks the window server for a picture of its own window — that window only, so nothing needs the Screen Recording permission — and quits. -glassine.shootCapture 1 asks for the fuller composite with the backdrop beneath, which the store pictures use; macOS counts that as screen recording and says so with a notice. docs/appstore/screenshots.sh uses this to take the store pictures, and it is how visual changes are checked without anyone sitting at the Mac.
The front door
glassine.ink is one static page insite/, served by Vercel from the same repository; a push to main publishes it too. site/vercel.json carries the redirects: glassinewriter.com and www. to glassine.ink, and short paths like /docs, /privacy, /changelog, /support and /download to where those live. Nothing on it changes often — everything that does lives here, in the manual.
This site
This site, docs.glassine.ink, lives indocs/site in the same repository and is built by Mintlify: docs.json is the navigation and *.mdx are the pages. A push to main publishes it within a minute or two. To preview locally:
mint validate and mint broken-links check a change before it goes up.
The rule for keeping it current is simple: a change that a person using Glassine would notice — a new key, a setting, a behaviour, a small delight — updates the page it belongs to and adds a line to the changelog in the same commit.
