Installed apps now show an 'Update available' button (menu bar) and can
one-click install signed updates. Adds the Sparkle dependency, an
UpdaterManager wired into AppState, the menu-bar banner + 'Check for
Updates', and Info.plist SUFeedURL (https://grammagem.app/appcast.xml),
SUPublicEDKey, and scheduled background checks.
Build / release:
- build.sh embeds + rpaths Sparkle.framework; sign-app.sh signs it
inside-out (XPC services, Updater.app, Autoupdate, framework, then app)
for a valid, notarizable signature.
- release.sh stamps the version, builds, signs, notarizes, staples, zips,
and emits the EdDSA-signed appcast.xml to upload to grammagem.app.
- A hidden --update-selftest checks a feed headlessly (CI/build pipeline).
Verified: a v0.1.0 build detects a v0.2.0 update against a local signed
appcast (UPDATE_FOUND: 0.2.0); the signed app passes codesign --strict.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the MLXEngine stub with real Qwen2.5-3B-4bit inference via
mlx-swift-examples (2.25.9): loads the local model snapshot on disk (no
network), chat-templated generation per AIAction, and tone classification.
Wired behind the existing AIEngine seam; AppState resolves the model dir
through ModelManager.
Build notes:
- arm64-only now (MLX is Metal / Apple-Silicon only; matches the spec).
- swift build (CLI) cannot compile mlx-swift's .metal kernels, so the
metallib is generated once via scripts/build-metallib.sh (xcodebuild) and
vendored at AppSupport/mlx.metallib; scripts/build.sh ships it as
Contents/Resources/mlx-swift_Cmlx.bundle/Contents/Resources/default.metallib
(the path mlx resolves, and it codesigns cleanly).
- A hidden --mlx-selftest entrypoint runs one headless generation to verify
the runtime end-to-end.
Verified: the signed app's self-test produces a real rewrite; full test
suite green (the MLX integration test is gated behind GRAMMAGEM_MLX_TEST).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- LiveMonitor: menu-bar–resident; reads the focused field via the Accessibility
API, runs the offline grammar engine, and shows live suggestions + a "Fix all".
- Menu-bar icon now reflects status (issue count / paused); added Pause/Resume.
- Page Blocker: exclude apps + websites (Safari domain detection) where GrammaGem
stays out of the way; hotkeys + monitoring suppressed there.
- build.sh now produces a universal (arm64 + x86_64) bundle; sign-notarize.sh is a
turnkey codesign→notarize→staple flow reading creds from env/keychain (no secrets).
- Clean entitlements plist (AMFI-compatible).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Native SwiftUI menu-bar app: global hotkey → capture selected text (AX API /
clipboard fallback) → grammar (Harper) / local AI (MLX) → replace in place.
Free/paid entitlement gate + Lemon Squeezy device-cap licensing, $0 marginal
cost per user. Heavyweight engines behind protocol stubs so it builds out of the box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>