flash

Privacy and permissions

Flash needs the Accessibility permission and nothing else to show hints and click. It never reads screen pixels, runs OCR, or records what you type in other apps, and it has no telemetry, analytics, crash reporting, or update checks.

This page lists everything else Flash and its bundled plugins may ask for, read, store, or send. Disable a plugin with [plugins] disabled = ["<id>"], and inspect running plugins with :plugins.

Permission prompts

Permission Asked by When
Accessibility Flash First launch. Required.
Automation: Safari, Chrome, and other Chromium browsers browsers The first time it lists tabs while that browser runs.
Automation: the app holding a stuck secure-input flag, and System Events Flash The first time a stuck hold is released by blurring a browser or sending its address-bar shortcut. A real password field does not ask.
Automation: Notes, Reminders, Contacts apple The first time it indexes that app.
Screen Recording screenshot The first :screenshot; macOS screencapture takes the picture.
Location network Only on an explicit :network refresh, to read the Wi-Fi name.
Calendars, Reminders, Contacts, … A command you configure yourself, such as icalBuddy in a status source The command’s first read. Flash itself never asks.

Plugins are child processes of Flash, so macOS attributes their requests to Flash. So are the commands you configure: a named source ([statusbar.sources.<name>]), a #() job in a status format or widget, and a terminal popup’s command. A calendar CLI such as icalBuddy reads Calendar through EventKit, so its first run makes macOS ask whether Flash may access your calendars, and the grant then covers Flash and every command it runs. Deny it to keep the command from reading Calendar; you can revoke it later in System Settings › Privacy & Security › Calendars. The clock and agenda example does this; khal, which reads its own files, does not.

Network

Flash’s core has no network features. Plugins that reach the network are listed below. answers uses the host’s fetch, which only reaches URLs allowlisted in its manifest, so the plugin process itself stays network-denied; the others make their own requests or run the CLI tools named here.

Plugin Destination When Default
answers www.ecb.europa.eu (daily exchange rates) At start, then every 6 hours On
github GitHub, through your gh CLI At launch, then when the flashlight opens at most every 10 minutes, only if gh is installed and signed in On
feed The URL you configure Every refresh_interval Off until url is set
tmux Noninteractive SSH to hosts running tmux Every few seconds Off: only hosts listed in [plugin.tmux] ssh_hosts
spotify Spotify, through the spotify_player CLI When you use it On use
third-party plugins GitHub (git clone of the pinned commit) When listed in [plugins] third_party Off

Data stored on your Mac

Path Contents
~/.config/flash/flash.toml Your configuration.
~/Library/Logs/Flash/ Logs. They never contain keys typed in other apps. Commands Flash’s command line cannot run are logged with their text; the trace level also logs every submitted command line and AX tree dumps.
~/Library/Application Support/Flash/command-history.json The last 200 entries you submitted in Flash’s command line, including flashlight queries.
~/Library/Application Support/Flash/clipboard/ Clipboard history: up to 1000 entries by default ([clipboard] history_size, 1–10000), readable only by you. Flash migrates existing history and images from Plugins/clipboard/share/ on first launch. This is a retention ceiling; Flash cannot recover copies made before it recorded them. The help page loads retained entries in bounded pages. Plain text is kept up to 128 KiB. Formatted HTML is kept up to 64 KiB. One image (PNG, JPEG, GIF, WebP, or a TIFF stored as PNG) is kept up to 4 MiB, including a preview when you copy a single image file of that size. A file copy records up to 20 paths. Items that password managers mark as concealed, transient, or auto-generated are never recorded.
~/Library/Application Support/Flash/Plugins/history/ Copies of Chrome’s History and Firefox’s places.sqlite, refreshed when the flashlight opens or you leave the browser, at most once a minute and only when the originals changed. They only feed explicit searches such as @firefox.history, never default results.
~/Library/Application Support/Flash/Plugins/marks/share/marks.json Up to 36 named app marks: each saved app’s process ID and bundle identifier.
~/Library/Application Support/Flash/ (other files) Ranking data for search results and plugin caches, such as exchange rates.

brew uninstall --cask --zap flash@nightly removes all of it.

Named yank registers stay in Flash process memory and are exposed to the local inspector’s Clipboard view while Flash runs. The unnamed (") and system clipboard (+) registers read the current macOS pasteboard; they are not stored as separate register files.

Data read from other apps

Keyboard

Flash reads keys only while it owns input: a hint overlay, normal mode, or its command line. A session event tap decides for each key whether Flash swallows it or passes it to the app; the tap never stores or logs keys. Modified global hotkeys use the standard macOS hotkey API. Flash does not request Input Monitoring.

While a password field has focus, macOS turns on secure input and hides keys from the tap. Flash respects it: a hint session started then takes Flash’s own key window instead, so the labels you type go to Flash and never to the password field. [app] keyboard_layout reads which input source is selected and its key layout, to match keys to hint labels; it records neither.

Secure input sometimes stays on after that field is gone, usually because a browser or a password manager enabled it in the background. Flash polls the flag (it cannot see keys while the flag is on) and, when the focused element is not a password field, asks the holding app to release it. A Chromium browser is told, through AppleScript, to blur the focused element in its open windows; the script does not read the field. If the flag remains, or the holder is Firefox or Safari, Flash brings that browser forward and sends the address-bar shortcut (the letter l with Command) via System Events, then returns to the app you were in. Any other holding app is activated and then left, which is what makes a background password manager drop the hold. The first of these can ask for Automation. Flash does not lock the screen, show a dialog, or read what you type. The log line names the app’s bundle id.

Screen capture

[overlay] screen_capture = "hide" asks macOS to leave Flash’s overlay, status bar and popups out of screenshots, recordings and screen sharing. It is a request other capture tools may ignore; recent macOS capture APIs can still record those windows.

Local CLI replies

flash status and flash doctor answer the flash command through the same local Apple Event that carries every other command, with JSON printed in your terminal. The reply describes Flash itself: its version, mode, permissions, key-capture path, input source ID, config path and diagnostic lines, plugin health, per-app hint counts and timings keyed by bundle ID (kept in memory for the last 50 activations of the 32 most recent apps, never on disk), and, for doctor, the name and process ID of an app holding secure input and whether Screen Recording is granted. It never contains clipboard contents, typed keys, window titles or hint targets, and nothing is sent over a network or written to disk. flash config_check runs entirely in the flash process and does not contact the resident.

Plugin isolation

Plugins are child processes that talk to Flash through JSON lines on stdin and stdout, and Flash stops them when it quits. Most bundled plugins run under a deny-by-default macOS sandbox profile built from their manifest: they may read files broadly (that is how history copies browser history databases), but never ~/.ssh, ~/.aws, ~/.config/gh, your Keychains, or another plugin’s data; they write only to their own data directory, run only the executables they declare, and reach the network only when they declare it. Six plugins run unsandboxed. Five execute helpers the sandbox forbids: caffeinate, github, screenshot, shortcuts, and tmux. The sixth, browsers, lists tabs over Apple Events, which Chrome and the other Chromium browsers refuse from any sandboxed sender, even with Automation granted.

Third-party plugins load only when listed in [plugins] third_party, and GitHub references must pin a full commit SHA.

Local inspector

:help, ?, :mappings, :logs, :plugins, and :commands open Flash’s help and runtime pages in your browser. Flash serves it on localhost (port 4242 by default) from the first such command until Flash quits, or from launch when [debug] http_inspector_enabled = true. It shows bundled documentation, app version and uptime, Accessibility/capture state, the configuration path and diagnostics, effective mappings for the focused app, logs, plugin state, and recent clipboard entries (text, images, formatted HTML, and file paths). The homepage remembers which of its guides this browser has opened, in that browser’s localStorage only; Flash does not receive the list. A loopback client can read the full retained clipboard history in pages, delete one entry, or fetch one stored image. It can also read the configuration file Flash loaded and, on Save, replace that file. Purge defaults returns text and does not write. The server writes only that file, and only after the text parses as TOML. Plugin setting values remain redacted. It rejects requests addressed to other host names and sends no CORS headers, so web pages cannot read it, but other programs on your Mac can while it runs.