Context-Aware Screenshot Tool for Hyprland.
OreGo is a CLI tool I wrote to make screenshots a bit smarter on Hyprland. Instead of just dumping files into a folder, it captures metadata like the window title, class, and workspace info and saves it to a local SQLite database. This makes it easier to find old screenshots later without scrolling through thousands of files named screenshot_123.png.
I wanted a way to search my screenshots. By storing metadata alongside the file path, you can:
- Search for screenshots by app name (e.g., all "Firefox" screenshots).
- Filter by window title.
- Keep track of context that is usually lost when you save an image.
It's a Go binary using Cobra for the CLI and SQLite for storage.
- Language: Go
- Database: SQLite
- Tools Used:
grim(for capturing)satty(for editing/annotation) - Hardcoded for now, but I might make this modular in the future.hyprctl(to get window info)tesseract(Optional, only for OCR)wl-copy(for clipboard support)
Fetches the active window's class and title before taking the shot.
Everything goes into ~/.local/share/orego/orego.db.
- List: See recent captures.
- Filter:
orego list --filter-by app firefox
If you have tesseract installed, you can use orego capture --ocr to grab text from the screen and copy it to your clipboard. It doesn't save the image to the DB in this mode.
orego cleanup checks if the files still exist and removes dead rows from the database.
You'll need grim, satty, wl-clipboard, and go. tesseract is optional if you want OCR.
pacman -S grim satty wl-clipboard go
# Optional for OCR:
pacman -S tesseract tesseract-data-enggit clone https://github.com/iMithrellas/OreGo.git
cd OreGo
go build -o orego cmd/orego/main.go
sudo mv orego /usr/local/bin/Takes a screenshot and opens satty. The database entry is created only after you save the file.
# Standard capture
orego capture
# Capture all visible workspaces
orego capture --all
# OCR (Copy text to clipboard)
orego capture --ocr# List recent
orego list
# Interactive TUI
orego list --tui
# TUI keys
# ? = help, g = open folder, C/Y = copy path, c/y = copy image, d = delete
# Filter
orego list --filter-by app firefox
orego list --filter-by title "GitHub"Open a screenshot by ID.
orego view 42Copy a screenshot to the clipboard by ID.
orego copy 42Print the full path to a screenshot.
orego path 42orego cleanupOreGo exposes a read-only manifest command used by Tarragon's system-plugin flow:
orego tarragon manifestThis command prints a stable TOML manifest to stdout with no side effects.
tarragon enable orego uses this output as the integration contract,
then rewrites entrypoint to OreGo's resolved absolute binary path.
The manifest uses orego as the stable plugin ID and OreGo as the display
name. Its prefix is the bare token orego; Tarragon applies the configured
global prefix symbol when routing queries (for example, @orego).
Tarragon then uses these on-call commands against the same entrypoint:
orego tarragon query "<text>"
orego tarragon select <result-id> [action]queryprints one JSON payload with screenshot results.selectexecutes againstresult-iddirectly (no prior query state required).- Supported actions are
open(default) anddelete.
On-call invocations receive TARRAGON_PLUGIN_ID, TARRAGON_PLUGIN_NAME,
TARRAGON_PLUGIN_DISPLAY_NAME, TARRAGON_PLUGIN_PREFIX, and
TARRAGON_PREFIX_SYMBOL from Tarragon. OreGo does not maintain a persistent
plugin connection, so the persistent-plugin hello handshake does not apply.
Put this in your hyprland.conf:
bind = $mainMod, S, exec, orego capture
bind = $mainMod SHIFT, S, exec, orego capture --ocr
bind = $mainMod CTRL, S, exec, orego capture --allUse ~/.config/orego/config.json to override commands and argument patterns.
{
"capture": {
"grim": {
"cmd": "grim",
"args_all": ["{{.Output}}"],
"args_single": ["-o", "{{.Monitor}}", "{{.Output}}"]
},
"editor": {
"cmd": "satty",
"args": ["-f", "{{.Input}}", "--output-filename", "{{.Output}}"],
"args_ocr": ["-f", "{{.Input}}", "-d", "--disable-notifications", "--output-filename", "{{.Output}}"]
},
"ocr": {
"cmd": "tesseract",
"args": ["{{.Input}}", "stdout", "-l", "eng+ces", "--psm", "6"]
},
"clipboard": {
"cmd": "wl-copy",
"args": []
},
"notify": {
"cmd": "notify-send",
"args": ["{{.Title}}", "{{.Body}}"]
}
}
}Template fields:
- Grim:
{{.Output}},{{.Monitor}} - Editor:
{{.Input}},{{.Output}} - OCR:
{{.Input}} - Notify:
{{.Title}},{{.Body}} - Clipboard: no template fields (stdin only)
You can still override just the command binaries per-run:
orego capture --grim-cmd grim --editor-cmd satty