Shirabe (調べ)
A Raycast-style quick-lookup overlay for Omarchy 4 (Quattro). Hit a hotkey, paste a word or concept, pick a lane, read, close.
| Lane | What you get | Backend | Typical latency |
|---|---|---|---|
| ✦ Ask | A tight explainer: one-line definition, then origin / usage / what it's confused with | codex exec on gpt-5.6-luna — your Codex subscription, no API key |
~10–14 s |
| Web | Top 5 DuckDuckGo results, plus an optional AI overview with cited sources | DuckDuckGo HTML (no key) + Codex with web_search=live |
links ~1 s · overview ~20 s |
| W Wiki | The Wikipedia article — best match via search, disambiguation pages listed, link to the page | Wikipedia REST + Action API | ~2 s |
Results render as Markdown with clickable links. Opening with text highlighted
pre-fills it as the query. Everything runs inside the long-lived omarchy-shell
process; no daemon, no extra service.
Requirements
- Omarchy 4.x (Quattro) — the Quickshell-based shell
- Codex CLI on
PATHand logged in (codex login) — for the Ask lane and the Web overview python3,curl,wl-clipboard(all present on a stock Omarchy install)
Without Codex the Web-links and Wiki lanes still work; Ask shows an error.
No sudo or pkexec is required. The plugin never writes to your configuration; enabling it, placing the bar button, and binding a hotkey are all explicit commands you run yourself (below).
Install
omarchy plugin add https://github.com/golden-acres-research/quattro-shirabe.git --enable
Add a hotkey to ~/.config/hypr/bindings.lua (pick any free chord):
o.bind("SUPER + SHIFT + SPACE", "Shirabe lookup", "omarchy-shell -q shell toggle ga-research.shirabe")
Hyprland reloads on save. Optionally put the magnifying-glass button on the bar:
omarchy bar put ga-research.shirabe --section right --before omarchy.tailscale
If the bar button logs
File name case mismatchright after install, runomarchy restart shell— see Gotcha below.
Using it
- Hotkey toggles the overlay.
- Bar icon: left-click toggles · right-click opens in the Web lane · middle-click opens in the Wiki lane.
- Scripts:
omarchy-shell shell toggle ga-research.shirabe omarchy-shell shell summon ga-research.shirabe '{"query":"umami","mode":"wiki"}'
| Key | Action |
|---|---|
Enter |
Run the lookup |
Tab / Shift+Tab |
Next / previous lane (re-runs the current query) |
Ctrl+1 Ctrl+2 Ctrl+3 |
Ask / Web / Wiki |
Ctrl+G |
Toggle the AI overview in the Web lane |
Ctrl+Y (or Ctrl+C with nothing selected) |
Copy the result as Markdown |
Ctrl+O |
Open the first link in the result and close |
Ctrl+B |
Open the query in your browser (Wikipedia / DuckDuckGo / ChatGPT) and close |
Ctrl+L |
Select the query text |
Ctrl+U |
Clear the query and forget the current selection (it won't be offered again) |
↑ ↓ PgUp PgDn |
Scroll the result |
Ctrl+, / |
Options pane (Esc goes back) |
Esc / click outside |
Close |
Options ( / Ctrl+,)
| Option | Default | Meaning |
|---|---|---|
| On close | Keep | Keep: the query and result stay for the next open (the query is pre-selected, so typing replaces it). Clear: closing forgets the query and result; the next open starts blank. |
| Prefill from selection | On | When you open Shirabe, text highlighted on screen is offered as the query (read-only, single line, ≤200 characters). Each selection is offered once: Wayland keeps the last selection around even after you deselect, so without this the same words would reappear on every open. Selecting something else (or re-selecting after that) offers it again; Ctrl+U forgets it on the spot, and On close → Clear forgets it too. |
Options persist in $XDG_CONFIG_HOME/shirabe/settings.json (~/.config/shirabe/settings.json),
re-read on every open, and are also settable over IPC:
omarchy-shell shell call ga-research.shirabe setOnClose clear # keep | clear
omarchy-shell shell call ga-research.shirabe setPrefillFromSelection false
omarchy-shell shell call ga-research.shirabe settings ''
Configuration
bin/shirabe-lookup reads these environment variables (set them for the shell
process, e.g. in ~/.config/hypr/envs.lua, or change the defaults at the top
of the script):
| Variable | Default | Meaning |
|---|---|---|
SHIRABE_MODEL |
gpt-5.6-luna |
Codex model for Ask and the Web overview |
SHIRABE_EFFORT |
low |
model_reasoning_effort passed to Codex |
SHIRABE_WIKI_LANG |
en |
Wikipedia language edition |
SHIRABE_WIKI_MAX_CHARS |
14000 |
Article body truncation |
The Ask / Web prompts are ASK_SYSTEM / WEB_SYSTEM in the same script.
Codex runs with -s read-only --ephemeral, so lookups never touch your files
or session history.
Try the backend on its own:
~/.config/omarchy/plugins/ga-research.shirabe/bin/shirabe-lookup wiki "liminal space"
~/.config/omarchy/plugins/ga-research.shirabe/bin/shirabe-lookup ask "sonder"
Layout
manifest.json overlay + bar-widget plugin manifest
Shirabe.qml the overlay (PanelWindow, exclusive keyboard focus, Markdown result pane)
ShirabeBar.qml bar button
bin/shirabe-lookup Python backend: ask | webai | links | wiki → Markdown on stdout
The overlay follows the [menu] surface of your Omarchy theme, so it matches
the rest of the shell on every theme, light or dark.
Security posture
Everything Shirabe shows comes from outside — search pages, Wikipedia, a
language model — and is rendered inside the long-lived omarchy-shell
process, so it is treated as untrusted at every hop:
- Bounded child processes.
bin/shirabe-lookupnever usescapture_output. Every child (curl and Codex) runs through onerun_bounded()runner that drains both pipes incrementally with hard byte caps: stdout is kept only up to its cap and the process group is killed the moment a child writes more; stderr is reduced to its last 4 KiB as it streams; a single deadline covers the run. curl additionally runs with--max-filesize(4 MiB). Codex is given no output file at all: its final message is read from the stdout pipe under a 256 KiB write-time cap, its event log (stderr) is allowed only a small tail, and the query itself is limited to 2000 characters. Nothing a child process does can grow a file on disk. The helper never prints more than 64 KiB. Search-result titles, snippets and hosts are Markdown-escaped; onlyhttp(s)result URLs are kept. - Bounded buffering in the shell.
Shirabe.qmlstreams helper stdout/stderr throughSplitParserinto capped buffers (64 KiB / 4 KiB); on overflow it kills the helper and marks the result truncated instead of collecting an unbounded stream. The primary-selection prefill is bounded the same way, and additionally byhead -cin its pipeline so an oversized selection owner cannot push more than ~1 KiB into the shell at all. - Inert Markdown. Before rendering,
sanitizeMarkdownneutralises inline HTML (<→<), turns images into plain links, defuses[ref]: urldefinitions, and reduces any non-http(s)link to its text. The shell never fetches a resource on behalf of a result.onLinkActivatedopenshttp(s)URLs only, viaQt.openUrlExternally. - Settings file is parsed defensively. The only file Shirabe writes is its
own
~/.config/shirabe/settings.json(atomic write); on read it is bounded to 4 KiB, must be a JSON object, and only known keys with known values are accepted — anything else falls back to defaults. - No privilege, no writes to your configuration. No sudo/pkexec; Codex runs
-s read-only --ephemeral; the plugin does not editshell.json,bindings.lua, or anything else.
Gotcha: Qt caches plugin directories
Qt 6.11's QML type loader caches a plugin directory's listing the first time it
loads anything from it. A .qml file created or renamed afterwards fails to
load asynchronously with File name case mismatch, even though the path is
correct. Editing existing files hot-reloads fine; after adding or renaming a
QML file (or right after omarchy plugin add in some cases), run
omarchy restart shell.
Uninstall
omarchy plugin disable ga-research.shirabe
omarchy plugin remove ga-research.shirabe
and delete the o.bind(...) line from ~/.config/hypr/bindings.lua.
License
MIT — see LICENSE.