Show HN: Sidekick – The zot coding agent, one click away on macOS A new macOS menu bar app called Sidekick provides one-click access to the zot coding agent from anywhere on the system, featuring a floating panel, global hotkey, and support for image queries. The app bakes the zot binary directly into its bundle and manages its own updates, eliminating the need for a separate zot installation. Sidekick requires macOS 26 or later and an API key from providers like Anthropic or OpenAI, though its use of third-party OAuth client IDs for subscription login may violate those services' terms of use. A macOS menu bar app that provides quick access to zot from anywhere on your system. Let zot sidekick whip up your emails: Let zot sidekick give your code a glow-up: Menu Bar Integration : Lives in your menu bar for quick access Global Hotkey : Long-press the Right Option key to toggle the panel from anywhere Floating Panel : Spotlight-style centered floating window that remembers its position and size Chat Interface : Clean, dark-themed chat interface with streaming responses Image Support : Drag and drop images for vision-based queries Sessions : Conversations auto-save and can be browsed, searched, reloaded, and deleted Working Directory : Set context for file operations Inline Settings : Configure provider, authentication API key or subscription , and model directly in the panel - macOS 26 or later - A recent Xcode the project targets the macOS 26 SDK - An Anthropic, OpenAI, etc. API key, or a supported subscription login Note on subscription login.The OAuth client IDs used are the ones published in Anthropic's Claude Code CLI, OpenAI's Codex CLI, and the Kimi Code CLI device-code flow. Reusing them from a third-party tool may be against their terms of service and may be revoked at any time. Use it at your own risk; the API-key flow is the safe default. The zot binary is baked into the app bundle , downloaded from the official GitHub releases https://github.com/patriceckhart/zot . No separate zot install is required, and the app never uses any zot on your system PATH. On launch the app checks the zot-sidekick releases https://github.com/patriceckhart/zot-sidekick/releases and compares the latest tag with its own version AppUpdater.swift . When a newer release exists, a small primary "Update" button appears in the panel top bar after Settings and Sessions that opens the latest release page. The app manages its own copy of the zot binary in Application Support and updates it entirely in Swift ZotUpdater.swift : - On launch and on demand it checks the GitHub releases API for the latest version. - When a newer version exists, Settings shows a primary "Update zot" button that downloads the correct darwin build for your architecture, extracts it, and atomically replaces the installed binary, then restarts the bridge. - The bundled in-app copy only seeds the first install; downloaded updates are preferred and are not overwritten unless a newer build ships in the app. No shell script is involved at runtime. scripts/bundle-zot.sh is a pre-release helper to refresh the binary that ships inside the app bundle. It is not part of the running app and does not affect the in-app update path. - Open zot sidekick.xcodeproj in Xcode - Build and run Cmd+R - Grant Accessibility for the global hotkey and "Paste into" via the menu bar icon's right-click menu "Open Accessibility Settings" ; Screen Recording is requested lazily the first time you take a screenshot - Open the panel and click the gear Settings in the top bar to configure authentication Menu Bar Click : Click the icon in the menu bar to toggle the panel Global Hotkey : Long-press the Right Option key about 0.4s to toggle it from anywhere Dismiss : Press Escape or click the menu bar icon again The panel remembers the position and size you drag it to across hide/show. It resets to the default centered position only when you quit and relaunch. - Type your question in the input field at the bottom - Press Enter or click the send button - Drag and drop images onto the window to include them in your query - Click "Copy" on any assistant response to copy it to clipboard - Click "Paste into …" to paste the response into your previously active application - Click the folder icon in the input bar to set a working directory - zot will use this directory as context for file operations - Conversations are saved automatically after each reply - Click "Sessions" in the panel top bar to browse, search, reload, or delete saved sessions - Sessions are stored as flat JSON files in ~/Library/Application Support/zot sidekick/sessions/ no project folders - Click "+ New" to start a fresh conversation - Click the gear Settings in the panel top bar to open settings inline - Configure: - Provider Anthropic, OpenAI, ChatGPT Subscription, Kimi, Google, DeepSeek, Ollama - Authentication: either a subscription login or an API key - Default Model - zot binary version, with a primary "Check for Updates" / "Update zot" button Providers that support subscriptions Anthropic Claude, ChatGPT, Kimi offer a "Log in with subscription" button. This runs the same OAuth flow as the zot CLI: - Anthropic and ChatGPT open a browser and capture the callback on a local loopback port PKCE . - Kimi uses the OAuth device flow a code plus a browser page . Tokens are written to the bundled binary's ZOT HOME/auth.json , so the embedded zot uses your subscription with no extra setup. API keys are stored the same way. Use "Sign Out" to remove stored credentials for a provider. The model picker shows models from every provider you are logged into, grouped by provider. The full live model list per provider is fetched via a one-shot zot rpc query ZotModelFetcher . Choosing a model from a different provider switches the active provider and restarts the bridge with its credentials. AppDelegate : Owns the menu bar icon, the panel, and the global hotkey HotkeyMonitor : Long-press Right Option detection CGEvent tap with an NSEvent fallback PanelController : Controls the floating panel window and remembers its frame PanelChatView : SwiftUI chat UI, including the inline settings overlay InlineSettingsView and the typing indicator AppState : Observable state management with @Observable , plus binary preparation and session/auth orchestration ZotBridge : Spawns and communicates with the bundled zot rpc process via JSON-RPC SessionStore : Flat-file JSON persistence for sessions no project folders ZotAuth / ZotOAuthLogin : API keys and subscription OAuth, written to ZOT HOME/auth.json ZotUpdater : GitHub release checks and in-Swift download/install of the bundled zot binary AppUpdater : Checks zot-sidekick releases and surfaces the in-app "Update" button ZotModelFetcher : One-shot RPC that fetches the full live model list per authenticated provider SettingsWindow : A standalone settings window legacy fallback; the inline panel settings are the primary path The app uses: - SwiftUI for the UI - Observation framework for state management - ScreenCaptureKit for screenshot functionality - Process for spawning the bundled zot binary - NWListener loopback servers for OAuth callbacks - Icon Composer Icon.icon for the Liquid Glass app icon, with a classic AppIcon.appiconset as the fallback for older macOS The app icon is an Icon Composer bundle Icon.icon . Because the CI runner's actool can crash compiling .icon , the catalog is precompiled on a Mac with a recent Xcode into prebuilt-icon/Assets.car plus Icon.icns via scripts/compile-icon.sh , committed, and injected into the built app by the workflow. Re-run that script and commit prebuilt-icon/ whenever the icon or asset catalog changes. The classic AppIcon.appiconset remains as a fallback for pre-26 macOS. .github/workflows/build-dmg.yml builds the app on macos-latest pinned to the latest Xcode on every push and on manual dispatch. It: - auto-versions each build from the run number with rollover 0.0.1 ... 0.0.99 - 0.1.0 ... 0.99.99 - 1.0.0 ... , - signs the app including the embedded zot binary with a Developer ID certificate and hardened runtime, then notarizes and staples the DMG, - packages a zot-sidekick-