A native macOS contextual AI assistant that stays in the menu bar and can be invoked anywhere.
Aski is a lightweight, native macOS assistant for asking AI about whatever is currently in front of you: selected text, a screenshot region, the active browser page, a pasted URL, or a plain question. It runs as a menu bar app, appears as a compact floating input panel, streams model responses in Markdown, and keeps API keys in the macOS Keychain.
It is built with SwiftUI + AppKit, not Electron.
Most AI chat apps require you to switch context: copy text, open a browser tab, paste into a chat window, explain what you were doing, and then move the answer back.
Aski is designed around the opposite workflow:
stay where you are, invoke a small panel, ask, and return to work.
It focuses on fast contextual questions across macOS applications:
- ask about selected text in any app;
- ask about a screen region through a screenshot;
- ask about the current browser page without manually copying the URL;
- search the web in the background and let the model summarize results;
- keep a searchable conversation history only when you choose to save it;
- copy answers as text or rendered PNG cards for sharing.
- Menu bar app with no Dock icon.
- Default hotkey: double-tap
Ctrl. - Supports custom hotkeys from Settings.
- Floating panel can stay compact or expand into a full conversation view.
Aski can collect context from multiple sources:
- selected text through Accessibility APIs with clipboard fallback;
- interactive screenshot selection for visual questions;
- frontmost app tracking;
- active browser URL reading for Safari, Chrome, Edge, Arc, Brave, and similar browsers;
- direct URL extraction from the user message.
- OpenAI-compatible streaming clients.
- Presets for DeepSeek and other compatible providers.
- Local Ollama auto-detection.
- Ollama model list updates as local models appear or disappear.
- Vision-capable Ollama models are detected through model capabilities.
- API keys are stored in macOS Keychain, not plaintext project files.
Aski can search or read web pages without opening a browser window:
/search <query>command;- natural-language search intent detection;
- DuckDuckGo HTML search fallback with no API key;
- background fetching and readable-text extraction from result pages;
- direct page reading for explicit URLs or the current browser tab.
- Streaming Markdown rendering.
- Headings, lists, quotes, tables, and syntax-highlighted code blocks.
- Copy as Markdown/plain text.
- Export answer cards as PNG for chat apps, docs, or social sharing.
- Optional insertion back into the previous app.
- Conversation saving is opt-in per session.
- SQLite storage with FTS5 search.
- Support for reopening, pinning, and deleting saved conversations.
- Image attachments are stored locally when conversation saving is enabled.
- Compact bar mode for quick questions.
- Expanded conversation mode for multi-turn work.
- History overlay.
- Configurable appearance themes, including a Memphis-style visual theme.
- Native SwiftUI/AppKit panel behavior, not a web wrapper.
┌─────────────────────────────┐
│ Menu Bar App │
│ SwiftUI + AppKit + NSPanel │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Invocation Layer │
│ Global hotkey / URL scheme │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Context Layer │
│ Selection / Screenshot / │
│ Browser URL / Frontmost App │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ LLM Layer │
│ OpenAI-compatible APIs / │
│ Ollama / Web retrieval │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Rendering & Storage │
│ Markdown / Cards / Keychain │
│ SQLite + FTS history │
└─────────────────────────────┘
Main source areas:
| Path | Purpose |
|---|---|
Sources/Aski/App |
app entry, menu bar lifecycle, URL scheme handling |
Sources/Aski/HotKey |
global hotkey detection and hotkey configuration |
Sources/Aski/Context |
selected text, screenshot capture, browser URL reading, frontmost app tracking |
Sources/Aski/LLM |
chat session, OpenAI-compatible streaming, Ollama client, web search/retrieval |
Sources/Aski/Window |
floating panel, input bar, Markdown renderer, history UI |
Sources/Aski/Settings |
model providers, appearance, shortcuts, settings window |
Sources/Aski/Storage |
Keychain API-key storage and SQLite history |
Sources/Aski/Output |
copy, card export, and insertion output helpers |
- macOS 13 or later
- Swift 5.9 or later
- Accessibility permission for global hotkeys and selected-text workflows
- Screen Recording permission for screenshot-based questions
- At least one configured model provider, or a running local Ollama instance
Recommended app bundle build:
./build_app.sh
open Aski.appFor development:
swift build
swift run AskiThe .app flow is recommended because macOS privacy permissions are tied to the signed app identity. Running the raw SwiftPM executable may cause Accessibility or Screen Recording authorization to be unstable across rebuilds.
Aski needs macOS permissions for specific workflows:
| Permission | Used for |
|---|---|
| Accessibility | global hotkey, selected-text capture, optional insertion back into the previous app |
| Screen Recording | interactive screenshot selection and visual question workflows |
| Automation / Apple Events | reading the current browser tab URL when you ask about the current page |
If permissions stop working after rebuilding, remove the old Aski entry in System Settings and add the newly built Aski.app again. Screen Recording changes usually require restarting the app.
Open Aski from the menu bar and go to Settings.
Supported model paths:
- DeepSeek and other OpenAI-compatible APIs;
- manually configured providers with Base URL, model name, and API key;
- local Ollama models discovered automatically.
API keys are stored in the macOS Keychain. They should never be committed to the repository.
- Select text in any app.
- Double-tap
Ctrl. - Ask a question.
- Press Enter.
- Double-tap
Ctrl. - Click the screenshot button.
- Select a region.
- Ask a question with a vision-capable model.
/search best local llm models for macOS
or ask naturally:
帮我搜一下最近的本地大模型工具
Aski searches in the background, fetches readable text from result pages, and streams a model-generated summary.
When invoked from a supported browser, prompts such as:
总结这个网页
can trigger active-tab URL reading and background page extraction.
Aski is local-first in its app architecture:
- API keys are stored in Keychain.
- Conversation history is saved only when enabled.
- Local Ollama models can be used without sending prompts to cloud providers.
- Web retrieval is explicit: search or page-reading is triggered by commands or clear intent.
- Screenshot and selected-text context are used for the current request and are not stored unless conversation saving is enabled.
- DuckDuckGo HTML search is a pragmatic fallback, not a guaranteed production search API.
- Some websites may block background fetching or return limited content.
- Selected-text capture can vary by application; Aski falls back to simulated copy where needed.
- Screenshot Q&A requires a model that supports images.
- Direct
swift runbuilds may require repeated macOS privacy permissions; usebuild_app.shfor stable app identity.
The public repository should contain source code, scripts, icons, and documentation only.
Do not commit:
- API keys or provider secrets;
.envfiles;- build products such as
.app,.dmg,.zip; - SwiftPM build cache
.build/; - local conversation databases or screenshots.
No open-source license has been selected yet. Until a license is added, all rights are reserved by default.