{"id":49480383,"url":"https://github.com/sfegette/grapfel","last_synced_at":"2026-04-30T22:05:58.857Z","repository":{"id":351191985,"uuid":"1204566556","full_name":"sfegette/grapfel","owner":"sfegette","description":"macOS menubar app for Apple Intelligence — 100% free, no API keys, no cloud, powered by apfel","archived":false,"fork":false,"pushed_at":"2026-04-14T01:44:53.000Z","size":1168,"stargazers_count":1,"open_issues_count":7,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T02:24:11.681Z","etag":null,"topics":["apfel","apple-intelligence","macos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sfegette.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-08T05:59:48.000Z","updated_at":"2026-04-14T01:44:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sfegette/grapfel","commit_stats":null,"previous_names":["sfegette/grapfel"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/sfegette/grapfel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfegette%2Fgrapfel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfegette%2Fgrapfel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfegette%2Fgrapfel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfegette%2Fgrapfel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sfegette","download_url":"https://codeload.github.com/sfegette/grapfel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sfegette%2Fgrapfel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32478217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"ssl_error","status_checked_at":"2026-04-30T13:12:06.837Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apfel","apple-intelligence","macos"],"created_at":"2026-04-30T22:05:58.300Z","updated_at":"2026-04-30T22:05:58.835Z","avatar_url":"https://github.com/sfegette.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# grapfel\n\nA 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](https://github.com/Arthur-Ficial/apfel).\n\n\u003e **Requires macOS 26 Tahoe (beta) and Apple Silicon.** Apple Intelligence must be enabled on your device.\n\n---\n\n## what it does\n\ngrapfel 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.\n\n- **no API keys** — runs entirely on-device via Apple Intelligence\n- **no cloud** — your prompts never leave your Mac\n- **no Ollama** — uses Apple's own foundation model, not a third-party runtime\n- **fast** — apfel's server mode keeps the model loaded; responses start in ~1 second\n- **persistent conversations** — pick up exactly where you left off between sessions\n\n---\n\n## requirements\n\n| Requirement | Details |\n|---|---|\n| macOS | 26 Tahoe (beta) or later |\n| Hardware | Apple Silicon (M-series) |\n| Apple Intelligence | Must be enabled in System Settings |\n| [apfel](https://github.com/Arthur-Ficial/apfel) | v0.9.0+ — see install below |\n\n---\n\n## download\n\n\u003e **This is an unsigned build.** You must bypass Gatekeeper to run it — see instructions below.\n\nDownload the latest release from the [Releases page](https://github.com/sfegette/grapfel/releases).\n\n### install from zip\n\n1. Download **grapfel-0.1.0-macos26.zip** from the Assets section of the release.\n2. Unzip and move `grapfel.app` to `/Applications`.\n3. **Bypass Gatekeeper** — pick either method:\n\n   **Option A — Terminal (recommended):**\n   ```bash\n   xattr -dr com.apple.quarantine /Applications/grapfel.app\n   ```\n   **Option B — Finder:** Right-click `grapfel.app` → **Open** → click **Open** in the dialog.\n\n4. Launch. The **✦** icon appears in your menubar.\n\n\u003e **Why unsigned?** Notarization requires an Apple Developer Program membership. Since grapfel targets macOS 26 beta users who are all developers, the Gatekeeper bypass above is the standard workflow.\n\n---\n\n## install apfel\n\ngrapfel requires `apfel` to be installed and available on your PATH.\n\n```bash\nbrew tap Arthur-Ficial/tap\nbrew install apfel\n```\n\nVerify it works:\n\n```bash\napfel \"say hello\"\n```\n\n---\n\n## install grapfel\n\ngrapfel can be installed from a pre-built zip (see [download](#download) above) or built from source.\n\n### build from source\n\n1. Clone the repo:\n   ```bash\n   git clone https://github.com/sfegette/grapfel.git\n   cd grapfel\n   ```\n\n2. Open the project in Xcode 26:\n   ```bash\n   open grapfel.xcodeproj\n   ```\n\n3. Select your Mac as the run destination and press **⌘R**.\n\nThe app will appear in your menubar as a ✦ icon.\n\n\u003e **Note:** The global hotkey (⌘⇧Space) uses Carbon `RegisterEventHotKey` and does not require Input Monitoring permission.\n\n---\n\n## usage\n\n| Action | How |\n|---|---|\n| Open / close | Click menubar icon, or press **⌘⇧Space** from anywhere |\n| Send prompt | Press **Enter** |\n| Insert newline | Press **⌘+Enter** |\n| New conversation | Click the ✏ icon in the header (appears once a conversation is active) |\n| Copy response | Click **Copy** at the bottom of any assistant message |\n| Copy as code block | Right-click **Copy** → \"Copy as Code Block\" |\n| Copy as plain text | Right-click **Copy** → \"Copy as Plain Text\" |\n| Attach file | Click the paperclip button |\n| Adjust options | Click the options disclosure group (temperature, max tokens, etc.) |\n| Preferences | Press **⌘,** or click the gear icon |\n\n---\n\n## conversations\n\ngrapfel maintains full multi-turn conversation history. Each message you send includes the complete prior context so the model can refer back to earlier turns.\n\nConversation 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.\n\nTo start fresh, click the **✏** (compose) icon in the header. This clears the history and deletes the saved state.\n\n---\n\n## copying responses\n\nEvery assistant response has a **Copy** button at the bottom of its bubble. Tap to copy, or right-click for options:\n\n| Option | What you get |\n|---|---|\n| Copy (tap) | Raw text — preserves Markdown syntax |\n| Copy as Markdown | Same as above, explicitly labelled |\n| Copy as Code Block | Response wrapped in ` ```markdown ``` ` — useful for embedding in docs |\n| Copy as Plain Text | Markdown syntax stripped — clean text for pasting anywhere |\n\nA brief **Copied ✓** confirmation appears for 2 seconds after copying.\n\n---\n\n## options\n\nThe options panel exposes the main apfel generation parameters:\n\n| Option | Default | Notes |\n|---|---|---|\n| Temperature | 1.0 | Controls randomness (0.0–2.0) |\n| Max tokens | 2048 | Maximum response length |\n| Seed | — | Optional fixed seed for reproducibility |\n| Streaming | off | SSE streaming — pending apfel v0.9.x fix |\n| Permissive | off | Disables content safety filtering |\n| System prompt | — | Sets the system role message |\n| Context strategy | newest-first | How conversation history is managed |\n\n---\n\n## architecture\n\n```\ngrapfel (menubar app)\n  └── launches apfel --serve on port 11434\n        └── wraps Apple's on-device foundation model\n              └── exposes OpenAI-compatible HTTP API at 127.0.0.1:11434/v1\n```\n\ngrapfel 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.\n\n```\nAppDelegate\n  ├── GrapfelPanel (NSPanel subclass — Liquid Glass, borderless, canBecomeKey)\n  ├── ApfelServerManager (actor — subprocess lifecycle)\n  └── Carbon hotkey (⌘⇧Space, no Input Monitoring permission required)\n\nChatViewModel (@Observable @MainActor)\n  ├── history: [ChatMessage]   — full conversation context\n  ├── send()                   — appends turns, calls API, saves to disk\n  └── clearHistory()           — resets state and deletes saved file\n\nConversationView\n  ├── MessageRow (user: right/.quaternary, assistant: left/purple tint)\n  ├── MarkdownContent (fenced code blocks + AttributedString inline markdown)\n  └── CopyButton (tap = raw markdown; context menu = code block / plain text)\n```\n\n---\n\n## known limitations\n\n- **SSE streaming not yet working** — apfel v0.9.0 closes the connection on `stream: true` requests. Non-streaming works fine (~1s response time). Will be re-enabled when fixed upstream.\n- **Global hotkey is not yet configurable** — ⌘⇧Space is hardcoded; a settings UI is on the roadmap.\n- **macOS 26 only** — Apple Intelligence and Liquid Glass APIs require the macOS 26 SDK.\n\n---\n\n## roadmap\n\n- [x] Menubar icon + panel (Liquid Glass, GrapfelPanel)\n- [x] apfel server lifecycle management (start, health-check, crash-restart)\n- [x] Prompt → response via OpenAI-compatible API\n- [x] Options panel (temperature, max tokens, system prompt, etc.)\n- [x] Enter to send, ⌘+Enter for newline\n- [x] Global hotkey (⌘⇧Space, no Input Monitoring permission)\n- [x] Multi-turn conversation history with full context\n- [x] Conversation persistence (auto-save/restore across sessions)\n- [x] Markdown rendering (code blocks, bold, italic, inline code)\n- [x] Copy response (raw, code block, plain text)\n- [x] App icon (interim generated; final hand-crafted artwork pending)\n- [x] Build output to `build/Release/grapfel.app` (Release config)\n- [x] Release zip published to GitHub Releases (v0.1.0)\n- [ ] Configurable hotkey in Settings\n- [ ] Error UI for binary-not-found / server-start-failed\n- [ ] SSE streaming (blocked on apfel upstream fix)\n- [ ] Full test suite\n- [ ] Final icon artwork\n\n---\n\n## credits\n\n- [apfel](https://github.com/Arthur-Ficial/apfel) by Arthur-Ficial — the CLI/server that makes Apple Intelligence scriptable\n- Built with SwiftUI + Swift 6 on macOS 26 Tahoe\n\n---\n\n## license\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsfegette%2Fgrapfel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsfegette%2Fgrapfel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsfegette%2Fgrapfel/lists"}