A macOS menu bar app that shows a floating toolbar when you select text. Copy, search, look up, translate, speak, chat with AI, run shell commands, or build reusable LLM, JavaScript, key-binding, and pipeline actions.
- Copy / Cut - Clipboard operations on selected text
- Open URL - Open selected text as a URL in the default browser
- Run Command - Run selections that begin with an installed executable in Terminal, iTerm2, Ghostty, Alacritty, Warp, kitty, or WezTerm. Commands with chaining, substitution, redirection, or multiple lines require confirmation.
Search selected text with 7 built-in engines:
- Google, Bing, DuckDuckGo, Baidu, Sogou, 360 Search, Yandex
- Custom URL scheme or URL template using
{{query}}(for examplemyapporhttps://example.com/search?q={{query}})
- System Dictionary - macOS built-in dictionary
- Eudic - Launch Eudic with the selected word
- Custom App - Open any dictionary app via URL scheme
- App-based - Bob (via AppleScript), Eudic (via URL scheme)
- LLM-based - Translate using any configured LLM provider with 27 target languages including English, Chinese (Simplified/Traditional), Japanese, Korean, Spanish, French, German, and more
- DeepL - API-based translation
- System - Apple's built-in AVSpeechSynthesizer with multiple voices and languages
- ElevenLabs - High-quality API-based TTS with multiple models (v3, Turbo v2.5, Flash v2.5, Multilingual v2) and custom voice selection
Chat with AI about selected text in a floating panel with streaming responses and rich Markdown rendering.
- Source context awareness — the AI can read the source file (line-range) or web page (character-range) for deeper understanding
- Supports PDF files via PDFKit text extraction
- Tool calling with user approval before reading source content
- Copy or apply AI responses directly to the original selection
- Pinnable panel that persists across interactions
- Local session history with a configurable retention limit and controls to delete individual sessions or clear all history
5 built-in prompt templates, plus support for creating your own:
- Polish, Extract Actions, Summarize, Bulletize, Draft Email
Each action can output to a result window or edit text inline. LLM actions can optionally include bounded source context from the current file, PDF, or web page using {{CONTEXT}}, {{SOURCE_URL}}, {{APP_NAME}}, and {{BUNDLE_ID}}.
7 starter templates with JavaScriptCore execution, including async fetch support for HTTP/HTTPS requests:
- Title Case, URL Toolkit, JWT Decode, Format JSON, Convert Timestamps, Clean Up Escapes, Wrap as Quote
Scripts run in a separate helper process (Contents/Helpers/selectionbar-js-helper),
so a script that never terminates is killed at its deadline instead of tying up
SelectionBar. If the helper is missing, execution falls back to running in-process.
Chain existing JavaScript and LLM actions into an ordered workflow. Each step receives the previous step's output, allowing reusable actions to be composed without duplicating scripts or prompts.
Create shortcut actions in Actions > Built-in > Key Bindings to trigger app commands directly (for example cmd+b for Bold).
- Add multiple shortcut actions with custom names and icons
- Configure per-app shortcut overrides by bundle ID
- Built-in starters: Bold, Italic, Underline
Create per-app action profiles that replace the global custom-action list for a specific application. Profiles can select and reorder any configured key-binding, JavaScript, LLM, or pipeline action.
Require a modifier key (Option, Command, Control, or Shift) to activate the toolbar. Prevents the toolbar from appearing during normal text selection.
- Ignored Apps - Exclude specific applications from text selection monitoring
- Clipboard Fallback - Opt specific apps into a stricter copy-based selection fallback when Accessibility does not expose selected text; installed copies of WeChat and Telegram are prefilled
- Launch at Login - Auto-start SelectionBar on login
- Auto-Updates - Built-in update checking via Sparkle
- App Language - Follow the system language or select English, Japanese, or Simplified Chinese
- macOS 14.0 (Sonoma) or later
- Accessibility permission (to read and edit selections)
- Input Monitoring permission (to observe global mouse and keyboard events)
- Automation permission (optional, for browser page reading and app-specific integrations)
Building from source currently requires Xcode 26 with Swift 6.2 or later because the PermissionFlow dependency uses Swift tools version 6.2.
Grab the latest signed build from the
releases page, open the
DMG, and drag SelectionBar.app into /Applications. The app updates itself
via Sparkle after that.
git clone https://github.com/tacshi/SelectionBar.git
cd SelectionBar
./scripts/build-debug.sh
open SelectionBar.app- Launch the app - SelectionBar appears in the menu bar
- Grant Accessibility and Input Monitoring permissions when prompted
- Select any text in any application
- A floating toolbar appears with action buttons
- Click an action to process the selected text
Hold a configured modifier key while selecting text to activate the toolbar. When enabled, the toolbar will not appear unless the modifier key is held down.
SelectionBar reads selections through the Accessibility API and detects selection gestures using global event monitors. Both Accessibility and Input Monitoring are required; macOS may silently suppress either API when its permission is missing.
- Open SelectionBar > Settings > General > Permissions and check both statuses.
- In System Settings > Privacy & Security, make sure SelectionBar is enabled under both Accessibility and Input Monitoring.
- If either permission is already enabled but the app still does nothing, toggle it off and on again. Permission grants can become stale after an update or local rebuild changes the app binary.
- Quit and relaunch SelectionBar after changing Input Monitoring permission.
Check Ignored Apps in settings too: the toolbar is suppressed in any app listed there, and in password fields (macOS blocks synthetic events while secure input is active).
A few apps (Electron and Java-based ones especially) do not expose selections through the Accessibility API. For those, add the app under Clipboard Fallback in settings — SelectionBar will synthesize a copy and restore your clipboard afterwards.
Confirm the provider's API key is saved (Providers tab, use Test
Connection) and that the model ID is one your account can reach. For custom
OpenAI-compatible endpoints, the base URL must include the version path, e.g.
https://example.com/v1.
| Provider | Capabilities | Setup |
|---|---|---|
| OpenAI | LLM, Translation, Chat | API key required |
| OpenRouter | LLM, Translation, Chat | API key required |
| DeepL | Translation | API key required |
| ElevenLabs | Text-to-Speech | API key required |
| Custom OpenAI-compatible | LLM, Translation, Chat | Choose a provider preset or enter an OpenAI-compatible base URL and credential |
SPM package with four targets:
- SelectionBarApp - SwiftUI menu bar app, settings UI, provider configuration
- SelectionBarCore - Core library with selection monitoring, action handling, floating toolbar, chat
- SelectionBarJavaScriptEngine - JavaScriptCore execution engine, shared by the app and the helper
- SelectionBarJSHelper - One-shot child process that runs a single JavaScript action and exits
SelectionMonitordetects text selection via Accessibility APISelectionBarCoordinatorshows the floatingSelectionBarView- User clicks an action →
SelectionBarActionHandlerprocesses it - Results are displayed in
SelectionResultView, replaced inline, or shown inChatPanelView
- Swift 6 / SwiftUI
@Observable(Observation framework)- macOS Accessibility APIs
- PermissionFlow (Accessibility and Input Monitoring setup)
- JavaScriptCore (custom JS actions)
- MarkdownUI (chat response rendering)
- PDFKit (PDF text extraction)
- Sparkle (auto-updates)
- Keychain Services (secure credential storage)
English, Japanese, Simplified Chinese.
Issues and pull requests are welcome. Before opening a PR:
xcrun swift-format lint --recursive --strict Sources Tests Package.swift
swift build
swift testCI runs these checks on macOS 26 for every pull request. To apply formatting locally before running the checks:
xcrun swift-format --recursive --in-place Sources Tests Package.swift