The Fazm AI desktop agent on GitHub is a real Swift app, not a Python wrapper
Every other page that shows up for this query stops at "it's open source, it's local." This one walks the actual repo. What is in Desktop/. Why Package.swift pins macOS 14.0. What the four-layer accessibility-permission probe in AppState.swift is doing, and why it exists specifically because macOS 26 Tahoe caches TCC per process and returns stale "trusted" when the permission is in fact broken. Anchor fact: lines 431-504.
Package.swift dependencies
What a real consumer Mac app pulls in
What is inside the repo
Four top-level directories, one JSON changelog, one CLAUDE.md
The README shows a three-line tree but the repo has more moving pieces than most open-source Mac AI agents. Here is what each top-level item actually holds.
Desktop/
The main Swift/SwiftUI app target. 95 source files, 47,702 lines. Entry point is FazmApp.swift. Accessibility-permission probe lives in Sources/AppState.swift.
acp-bridge/
TypeScript bridge for Claude's Agent Client Protocol. Currently on ACP v0.25.0 (shipped in Fazm v2.1.2, 2026-04-07). Bundles browser-overlay-init scripts.
Backend/
Rust service for heavier media and transcription paths. Has its own Cargo.toml and Dockerfile. Not required to run the Swift app locally.
Installer/
DMG installer Swift package for distributing signed .app builds. Not code you edit as a contributor, code you run when you cut a release.
CHANGELOG.json
Structured JSON of every numbered release. 11 entries covering 2026-04-04 through 2026-04-16 alone. Every claim on the Fazm site maps to a version + date here.
CLAUDE.md
Developer guide for Claude Code agents working on the repo. Documents debug triggers (com.fazm.testQuery, com.fazm.control) and per-user SQLite DB locations.
From clone to running app
The exact sequence when you run ./run.sh
README's Development section has four lines. This is what those four lines actually produce on a fresh clone, including the first lines of the AppState accessibility log that appear as soon as the window opens.
./run.sh build pipeline
swift build
Compile ObjCExceptionCatcher
Compile 95 Swift files
Link Fazm.app
Launch Fazm.app
The anchor fact
AppState.swift lines 431-504: the four-layer AX permission probe
Open the file. This block is the single piece of code every other "open source Mac AI agent" repo is missing. It exists because AXIsProcessTrusted caches its result per process on macOS 26 Tahoe, so the system can report "trusted" when TCC has in fact revoked the permission. Layering a real AX call, an error-code switch, a Finder cross-check, and a CGEvent tap probe on top of each other is how you catch that.
Why the probe exists
A macOS 26 Tahoe session where the OS lies and the probe catches it
Real log shape, filtered to the AppState tag. The interesting line is the Finder cross-check. Without it, "cannotComplete" looks the same whether your permission is broken or the frontmost app is simply Qt and never implemented AX.
From GitHub checkout to any app on your Mac
The path from a git clone to a click inside, say, Numbers.app is not mysterious. It is four files in the repo and one OS primitive.
Source files -> AppState -> anything on the Mac
From zero to first query
Six steps you can run on a stock Mac today
1. Check macOS and Xcode
macOS 14.0 or later, Xcode installed, and an Apple Developer ID for code signing. These are the three lines in the README's Development section.
2. Clone the repo
git clone https://github.com/mediar-ai/fazm.git && cd fazm. Top-level tree is Desktop/, acp-bridge/, Backend/, Installer/, plus README, CHANGELOG.json, CLAUDE.md, and run.sh.
3. Run ./run.sh
The script kicks swift build against Desktop/Package.swift, resolves dependencies (GRDB, Sparkle, PostHog, Sentry, Firebase, Highlightr, macos-session-replay, ai-browser-profile-swift-light), and launches the resulting Fazm.app.
4. Grant Accessibility
On first launch the app calls AXIsProcessTrustedWithOptions and opens System Settings > Privacy & Security > Accessibility. AppState.swift:512 is the trigger. No accessibility means no desktop control, by design.
5. (Optional) ./reset-and-run.sh
Resets onboarding, permissions, and UserDefaults, then builds and launches. Use when you want a clean-slate run, e.g. when testing the onboarding flow after a local code change.
6. Trigger programmatically
Per CLAUDE.md, you can send a text query to the floating bar without touching voice or UI: xcrun swift -e 'import Foundation; DistributedNotificationCenter.default().postNotificationName(.init("com.fazm.testQuery"), object: nil, userInfo: ["text": "your query"], deliverImmediately: true)'. The same com.fazm.control notification supports newChat, setModel:, sendFollowUp:, and setWorkspace:.
Python 'computer use' agent vs the Fazm GitHub repo
A screenshot gets shipped to a cloud vision model. The model emits pixel coordinates. A pyautogui or robotjs call tries to translate those coordinates back onto a UI that may have already changed. No code signing, no notarization, no real app lifecycle, no handling for the stale per-process TCC cache macOS 26 Tahoe introduced. Lives as a script in a notebook, not a .app on your Dock.
- Pixel-coordinate actions drift per model version
- No native CGEvent taps or AXObserver subscriptions
- No Sparkle, no auto-update, no signed .app bundle
- No four-layer AX probe; trusts AXIsProcessTrusted at face value
The repo-level comparison most OSS Mac AI agents lose
Not a feature marketing grid. A grid of things you can verify by grepping the two repos.
| Feature | Typical Python OSS Mac agent | mediar-ai/fazm |
|---|---|---|
| Primary language | Python or JavaScript wrapper | Swift 5.9 (78.2% of repo), SwiftUI UI layer |
| Packaging | pip install or node run script | Swift Package Manager, .app bundle, DMG installer |
| Minimum OS declared | Often unstated or 'macOS any' | macOS 14.0 in Package.swift |
| UI interaction path | Screenshot + pixel coordinates | AXUIElementCreateApplication + AXUIElementCopyAttributeValue |
| TCC cache staleness on macOS 26 Tahoe | Trusts AXIsProcessTrusted result | Four-layer probe incl. CGEvent tap bypass |
| Auto-update | git pull + manual re-run | Sparkle 2.9+ wired in Package.swift |
| Error telemetry | Print statements | Sentry (8.57.x), PostHog (3.x) |
| Authentication | API key in env var | Firebase Auth (via firebase-ios-sdk 11+) |
| Local persistence | JSON or SQLite with raw sqlite3 | GRDB.swift 6.24+, typed migrations |
| Debug/control surface | CLI flags | com.fazm.control distributed notifications (12+ commands) |
Verifiable, not marketing
Clone the repo and run the commands
Everything above is derived from commands you can run against your own clone on April 17, 2026. The number of Swift files, the total line count, the Package.swift platform target, the file-and-line location of the probe, the CHANGELOG version numbers. If any of them drift as the repo grows, they drift for everyone, not just this page.
“AXError.cannotComplete is ambiguous: it can mean our permission is broken, OR that the frontmost app doesn't implement AX (e.g. Qt, OpenGL, Python-based apps like PyMOL). Confirm against Finder before concluding the permission is truly broken.”
Comment in Desktop/Sources/AppState.swift, lines 454-458
What the top search results on this query all skip
Gaps in every other page that ranks for this keyword
- The exact file path and line numbers (AppState.swift:431-504) for the AX probe
- Why the probe exists: macOS 26 Tahoe's per-process AXIsProcessTrusted cache staleness
- How cannotComplete is disambiguated against a known-good app (Finder)
- The event-tap tie-breaker using CGEvent.tapCreate with CGEventType.mouseMoved
- The actual Package.swift dependency list (GRDB, Sparkle, PostHog, Sentry, Firebase, Highlightr)
- The concrete 47,702-line / 95-file count you can verify with wc -l
- The com.fazm.control distributed notifications surface for programmatic testing
Frequently asked questions
Frequently asked questions
What is the Fazm GitHub repo and what language is it written in?
github.com/mediar-ai/fazm is the Fazm Desktop app for macOS. It is a native Swift/SwiftUI application distributed as a Swift Package (SPM), not a Python script or an Electron wrapper. The language breakdown per GitHub is 78.2% Swift, with a smaller TypeScript portion (the acp-bridge), and minor Shell, Rust, and JavaScript. The repo has four top-level pieces: Desktop/ (the Swift/SwiftUI macOS app), acp-bridge/ (TypeScript bridge for Claude's Agent Client Protocol), Backend/ (Rust, in Backend/Cargo.toml), and Installer/. The README labels it MIT licensed, free to start, fully open source, fully local. The README command to run it locally is ./run.sh.
Is Fazm actually a real macOS app or a Python research wrapper like most 'open source computer use' repos?
It is a real macOS app. The Desktop/ directory alone contains 95 Swift source files totaling 47,702 lines (run `find Desktop/Sources -name '*.swift' | xargs wc -l` to verify). Desktop/Package.swift declares macOS 14.0 as the minimum and Swift 5.9 as the tools version. It pulls in production-grade Apple ecosystem packages: GRDB.swift for SQLite, Sparkle for auto-update, Firebase iOS SDK for auth, PostHog and Sentry for telemetry, and Highlightr for syntax highlighting. It also depends on two Mediar-published Swift packages (m13v/macos-session-replay for session recording and m13v/ai-browser-profile-swift-light for browser profile control). None of these are things you pull into a research wrapper.
What makes Fazm's accessibility-API handling different from other open-source Mac AI agents?
The anchor file is Desktop/Sources/AppState.swift lines 431-504. It defines three methods that layer on top of each other to detect when the macOS TCC (Transparency, Consent, and Control) database has silently broken the app's accessibility permission: testAccessibilityPermission() makes a real AX call against the frontmost app; confirmAccessibilityBrokenViaFinder(suspectApp:) cross-checks Finder to disambiguate the ambiguous AXError.cannotComplete case (which can mean either 'our permission is broken' or 'this app doesn't implement AX', e.g. Qt, OpenGL, or Python-based apps); and probeAccessibilityViaEventTap() uses CGEvent.tapCreate as a tie-breaker when Finder is not running. The event-tap probe exists because AXIsProcessTrusted caches its result per-process on macOS 26 Tahoe and can return stale 'trusted' when TCC is actually broken. No other open-source macOS AI agent repo ships this logic.
What are the exact AXError cases that AppState.swift handles?
Four. .success, .noValue, .notImplemented, and .attributeUnsupported are all treated as 'AX is working' (noValue means the app has no windows, notImplemented/attributeUnsupported mean the app is just AX-incompatible, not that permission is broken). .apiDisabled is treated as 'permission is stuck' with no confirmation needed because it is unambiguous and logged as ACCESSIBILITY_CHECK: AXError.apiDisabled. .cannotComplete is ambiguous and triggers the Finder cross-check path. Any other error code is logged as 'not permission-related, treating as OK'. The switch lives in testAccessibilityPermission() at roughly line 444.
How do I actually run Fazm from the GitHub repo on my Mac?
Requirements in the README: macOS 14.0 or later, Xcode, and an Apple Developer ID for code signing. Clone the repo, cd into it, and run ./run.sh (builds the Swift app and launches it) or ./reset-and-run.sh (performs a clean-slate run, resets onboarding, permissions, and UserDefaults). There is a CLAUDE.md in the repo root that also documents debug triggers via distributed notifications: you can run 'xcrun swift -e ...com.fazm.testQuery...' to send a text query programmatically to the floating bar without touching voice or the UI. That programmatic control surface (com.fazm.control) is itself documented in CLAUDE.md, with commands like newChat, setModel:claude-sonnet-4-6, sendFollowUp:<text>, and setWorkspace:<path>.
What Swift packages does Fazm's Desktop app depend on?
The dependency list in Desktop/Package.swift (version 5.9 Swift tools, macOS 14.0 minimum): PostHog/posthog-ios from 3.0.0, getsentry/sentry-cocoa pinned to 8.57.3..<8.58.0, groue/GRDB.swift from 6.24.0 (SQLite), sparkle-project/Sparkle from 2.9.0 (auto-update framework), gonzalezreal/swift-markdown-ui from 2.4.0, firebase/firebase-ios-sdk from 11.0.0 (used for FirebaseCore and FirebaseAuth), m13v/macos-session-replay from 0.7.0, a local Highlightr package under LocalPackages/, and m13v/ai-browser-profile-swift-light from 0.1.0. There is also an ObjCExceptionCatcher target compiled as a plain Objective-C helper. This is a production-app dependency graph, not a notebook-style stack.
Does Fazm use screenshots or vision models to control the Mac?
No. The primary desktop-control path goes through native macOS Accessibility APIs: AXUIElementCreateApplication, AXUIElementCopyAttributeValue, and related CoreFoundation calls. Screenshot-based vision is not how buttons get clicked or forms get filled. This is why the permission probe in AppState.swift is load-bearing: if AX breaks, the agent is blind. The entire premise of 'any app on your Mac, not just the browser' depends on a reliable accessibility tree, which is why the repo ships four fallback layers (AX call, error-code classification, Finder cross-check, CGEvent tap probe) to detect when macOS has silently revoked that tree.
Where are the tests and what can I actually verify before committing?
Clone the repo and run these commands against the working tree. 'find Desktop/Sources -name "*.swift" | wc -l' should return 95. 'find Desktop/Sources -name "*.swift" | xargs wc -l | tail -1' should show 47702 total lines. 'cat Desktop/Package.swift | grep platforms' should show .macOS("14.0"). 'cat CHANGELOG.json | grep -c "\"version\""' should show 11 releases just in the window the file covers. 'grep -n AXUIElement Desktop/Sources/AppState.swift' should return the four hits at lines 439, 441, 470, 472. Every number in this guide is derived from running one of those commands against the repo on April 16-17, 2026.
What is the acp-bridge and why is it in TypeScript?
acp-bridge/ is the Fazm side of the Agent Client Protocol (ACP), the wire protocol the Swift chat provider uses to talk to the Claude agent runtime. TypeScript is the language of the Claude Code / Anthropic agent-side tooling, so the bridge lives in TS where those libraries are first-class. CHANGELOG.json entry v2.1.2 on 2026-04-07 reads 'Upgraded ACP protocol to v0.25.0 with improved error handling for credit exhaustion and rate limits' - that upgrade landed on the TypeScript side and the Swift side consumes the new typed error frames. The split is deliberate: Swift for the native UI and macOS system calls, TypeScript for the protocol bridge, a small Rust backend in Backend/ for high-throughput media work.
How does Fazm compare to other open-source macOS AI agents on GitHub in 2026?
Most 'open source computer use' repos in 2026 are Python or Node wrappers around a cloud vision model that receive screenshots and emit pixel coordinates. Fazm inverts this: it is a code-signed native macOS app, built with Swift/SwiftUI, reads the accessibility tree directly, and treats hosted models (Claude Opus, GPT-5.4-Cyber) as interchangeable endpoints behind ANTHROPIC_BASE_URL. The comparison matters for three reasons: accessibility-tree tools are structured text (cheap, fast, reliable) where screenshot tools are pixels (expensive, slow, drift per model); a native app can claim macOS 14.0+ system capabilities like CGEvent taps and AXObserver that a sandboxed Python agent cannot; and a real .app bundle can ship Sparkle auto-updates, Firebase auth, and code signing, which matter for a consumer app but do not matter for a research notebook.
Clone the repo, run ./run.sh, open AppState.swift
Everything on this page is grep-able in github.com/mediar-ai/fazm as of April 17, 2026. Desktop/Package.swift for the dependency graph. Desktop/Sources/AppState.swift lines 431-504 for the four-layer accessibility probe. CHANGELOG.json for version-by-version history. Or just download the signed .app from fazm.ai and skip the build.
Open the repo →
Comments
Public and anonymous. No signup.
Loading…