Skip to content

sfegette/grapfel

Repository files navigation

grapfel

A native macOS menubar app that puts Apple Intelligence at your fingertips — no API keys, no cloud, no Ollama. Powered entirely by on-device inference via apfel.

Requires macOS 26 Tahoe (beta) and Apple Silicon. Apple Intelligence must be enabled on your device.


what it does

grapfel sits in your menubar. Click the icon (or press ⌘⇧Space from anywhere) to open a lightweight prompt window, type your request, hit Enter to send, and get a response from the on-device foundation model — instantly, privately, offline.

  • no API keys — runs entirely on-device via Apple Intelligence
  • no cloud — your prompts never leave your Mac
  • no Ollama — uses Apple's own foundation model, not a third-party runtime
  • fast — apfel's server mode keeps the model loaded; responses start in ~1 second
  • persistent conversations — pick up exactly where you left off between sessions

requirements

Requirement Details
macOS 26 Tahoe (beta) or later
Hardware Apple Silicon (M-series)
Apple Intelligence Must be enabled in System Settings
apfel v1.3.3+ — see install below

download

Download the latest release from the Releases page.

install from zip

  1. Download the latest grapfel-X.Y.Z-macos26.zip from the Assets section of the release.
  2. Unzip and move grapfel.app to /Applications.
  3. Launch. The icon appears in your menubar.

grapfel is signed with a Developer ID certificate and notarized by Apple — no Gatekeeper prompt, no quarantine step required.


install apfel

grapfel requires apfel to be installed and available on your PATH.

brew install apfel

apfel is in homebrew-core as of v1.0.0. The tap (brew tap Arthur-Ficial/tap) is no longer required.

Verify it works:

apfel "say hello"

install grapfel

grapfel can be installed from a pre-built zip (see download above) or built from source.

build from source

  1. Clone the repo:

    git clone https://github.com/sfegette/grapfel.git
    cd grapfel
  2. Open the project in Xcode 26:

    open grapfel.xcodeproj
  3. Select your Mac as the run destination and press ⌘R.

The app will appear in your menubar as a ✦ icon.

Note: The global hotkey (⌘⇧Space) uses Carbon RegisterEventHotKey and does not require Input Monitoring permission.


usage

Action How
Open / close Click menubar icon, or press ⌘⇧Space from anywhere
Send prompt Press Enter
Insert newline Press ⌘+Enter
New conversation Click the ✏ icon in the header (appears once a conversation is active)
Copy response Click Copy at the bottom of any assistant message
Copy as code block Right-click Copy → "Copy as Code Block"
Copy as plain text Right-click Copy → "Copy as Plain Text"
Attach file Click the paperclip button
Adjust options Click the options disclosure group (temperature, max tokens, etc.)
Preferences Press ⌘, or click the gear icon

conversations

grapfel maintains full multi-turn conversation history. Each message you send includes the complete prior context so the model can refer back to earlier turns.

Conversation state is automatically saved to ~/Library/Application Support/grapfel/conversation.json — when you reopen the window (or relaunch the app), your conversation is restored exactly as you left it.

To start fresh, click the (compose) icon in the header. This clears the history and deletes the saved state.


copying responses

Every assistant response has a Copy button at the bottom of its bubble. Tap to copy, or right-click for options:

Option What you get
Copy (tap) Raw text — preserves Markdown syntax
Copy as Markdown Same as above, explicitly labelled
Copy as Code Block Response wrapped in ```markdown ``` — useful for embedding in docs
Copy as Plain Text Markdown syntax stripped — clean text for pasting anywhere

A brief Copied ✓ confirmation appears for 2 seconds after copying.


options

The options panel exposes the main apfel generation parameters:

Option Default Notes
Temperature 1.0 Controls randomness (0.0–2.0)
Max tokens 2048 Maximum response length
Streaming on SSE streaming — token-by-token output as the model generates
JSON mode off Requests structured JSON output (response_format: json_object)
System prompt Sets the system role message

Token usage (prompt / completion / total) is shown beneath each response.

Permissive mode (disables content safety filtering) is a server-level setting — enable it in Settings → General. The server restarts automatically when toggled.


architecture

grapfel (menubar app)
  └── launches apfel --serve on port 11434
        └── wraps Apple's on-device foundation model
              └── exposes OpenAI-compatible HTTP API at 127.0.0.1:11434/v1

grapfel manages the apfel --serve process lifecycle: starts it on launch, health-checks it, restarts on crash, and terminates it cleanly on quit. All communication is over localhost — nothing touches the network.

AppDelegate
  ├── GrapfelPanel (NSPanel subclass — Liquid Glass, borderless, canBecomeKey)
  ├── ApfelServerManager (actor — subprocess lifecycle)
  ├── ServerState (@Observable — propagates .starting/.running/.binaryNotFound/.startFailed to UI)
  └── Carbon hotkey (⌘⇧Space, no Input Monitoring permission required)

ChatViewModel (@Observable @MainActor)
  ├── history: [ChatMessage]   — full conversation context
  ├── send()                   — appends turns, calls API, saves to disk
  └── clearHistory()           — resets state and deletes saved file

ConversationView
  ├── MessageRow (user: right/.quaternary, assistant: left/purple tint)
  ├── MarkdownContent (fenced code blocks + AttributedString inline markdown)
  └── CopyButton (tap = raw markdown; context menu = code block / plain text)

updates

grapfel uses Sparkle for automatic updates. Right-click the menubar icon → Check for Updates… to check manually, or let it check in the background automatically.


known limitations

  • Global hotkey is not yet configurable — ⌘⇧Space is hardcoded; a settings UI is on the roadmap (#8).
  • macOS 26 only — Apple Intelligence and Liquid Glass APIs require the macOS 26 SDK.

roadmap

  • Menubar icon + panel (Liquid Glass, GrapfelPanel)
  • apfel server lifecycle management (start, health-check, crash-restart)
  • Prompt → response via OpenAI-compatible API
  • Options panel (temperature, max tokens, system prompt, etc.)
  • Enter to send, ⌘+Enter for newline
  • Global hotkey (⌘⇧Space, no Input Monitoring permission)
  • Multi-turn conversation history with full context
  • Conversation persistence (auto-save/restore across sessions)
  • Markdown rendering (code blocks, bold, italic, inline code)
  • Copy response (raw, code block, plain text)
  • App icon (interim generated; final hand-crafted artwork pending)
  • Build output to build/Release/grapfel.app (Release config)
  • Release zip published to GitHub Releases (v0.1.0)
  • Error UI for binary-not-found / server-start-failed (first-launch onboarding)
  • SSE streaming (enabled — apfel 1.3.3)
  • Sparkle auto-update (v0.1.3)
  • Developer ID signed + notarized (v0.1.3)
  • apfel version check + upgrade nudge (v0.1.3)
  • Token usage display (v0.1.3)
  • JSON mode (v0.1.3)
  • Permissive mode in Settings (v0.1.3)
  • Configurable hotkey in Settings (#8)
  • Full test suite (#10)
  • Final icon artwork (#9)

credits

  • apfel by Arthur-Ficial — the CLI/server that makes Apple Intelligence scriptable
  • Built with SwiftUI + Swift 6 on macOS 26 Tahoe

license

MIT

About

macOS menubar app for Apple Intelligence - 100% free, no API keys, no cloud, powered by apfel

Topics

Resources

Stars

Watchers

Forks

Contributors