Omahub
← All plugins
G

Omasend

by Gavin Nugent

LocalSend-compatible file transfer and messaging, native to the shell: discover devices on the LAN or tailnet, send files and messages, and receive them whenever the shell is running — no app open required. Summon with: omarchy-shell shell toggle nosignal.omasend

Security review

Review recommended · 10 findings

Deterministic scan — not a security guarantee

Medium
Risk level
Medium
Analyzed commit
ccb0950
Scanned
2 weeks ago
  • medium external_hosts install.sh:105

    Downloads or connects to an external HTTP(S) host.

    git clone https://github.com/$REPO.git"
  • medium sudo install.sh:149

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo reads from /dev/tty so the
  • medium sudo install.sh:154

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo pacman -S --needed --noconfirm zenity </dev/tty; then
  • medium sudo install.sh:158

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo pacman -S zenity"
  • Command runs with sudo, elevating the process beyond the plugin environment.

    sudo pacman -S go
  • Docs external_hosts README.md:48

    Downloads or connects to an external HTTP(S) host.

    git clone https://github.com/28allday/omasend-quattro.git
  • Docs sudo README.md:33

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo pacman -S go`). It's a deliberate choice: the thing that
  • Docs sudo README.md:93

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo pacman -S go`), and
  • Docs sudo README.md:259

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo pacman -S zenity`. No shell restart
  • Docs sudo README.md:300

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo pacman -S zenity`, only

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
ccb0950
Reviewed
2 weeks ago

The plugin is a LocalSend-compatible file transfer tool with a well-structured Go engine and QML UI. The deterministic scan flagged external hosts and sudo usage, but these are standard installation steps (cloning the repo, installing Go/zenity) that are clearly documented and user-consented. The code shows strong security practices: socket path hardening, fingerprint pinning, checksum-verified prebuilt binaries, and no obfuscation or hidden behavior.

  • The install.sh uses sudo to install zenity, but only when missing and with a clear prompt; this is a standard package-manager action.
  • The README documents a curl-piped install, but that is illustrative and not part of the plugin's executable code.
  • The engine listens on a network port (53317) and accepts incoming connections, which is the intended functionality; users should be aware of the exposure.
  • The optional --agent-context flag writes to ~/.claude/CLAUDE.md, but it is opt-in and clearly documented.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/28allday/omasend-quattro --enable
System #bar #quickshell #system

Omasend

Send and receive files and messages between your Omarchy desktop and anything running LocalSend — phones, laptops, other Linux boxes — without opening an app. Omasend is a native plugin for the Omarchy 4 desktop shell (omarchy-shell): a paper-plane icon in the bar, a panel for devices, messages and transfers, and an always-on receiver that runs quietly with the shell.

It speaks the LocalSend v2.1 protocol, including the default encrypted (HTTPS) mode, so stock LocalSend apps see it as just another device.

<p align="center"> <img src="docs/devices.png" width="32%" alt="Devices tab"> <img src="docs/staged.png" width="32%" alt="Files staged for sending"> <img src="docs/offer.png" width="32%" alt="Incoming file offer"> </p>

Quick start

On an Omarchy 4 desktop, add the plugin the standard way:

omarchy plugin add https://github.com/28allday/omasend-quattro.git --enable

Click the paper-plane icon in the bar to open the panel. Transfers are handled by a small companion binary — the engine — which a plugin install can't place on its own, so the first time you open the panel head to Settings › Engine and press Set up engine.

That compiles the engine from the source sitting in the plugin's own checkout, which needs Go (sudo pacman -S go). It's a deliberate choice: the thing that listens on your network is built from code you can read in the same directory, rather than a binary you have to take on trust.

Prefer the terminal? The same script the button runs:

~/.config/omarchy/plugins/nosignal.omasend/bin/omasend-setup

There's also install.sh in the repo, which does the above plus the optional extras — the bar icon, the Nautilus right-click entry and zenity. Run it from a clone:

git clone https://github.com/28allday/omasend-quattro.git
cd omasend-quattro && bash install.sh

Then, on the devices you want to talk to:

  • Phone or tablet — install the free LocalSend app (iOS / Android). On the same Wi-Fi, it and your desktop find each other automatically.
  • Another desktop or laptop — the official LocalSend app, or Omasend on another Omarchy 4 box.
  • A headless server — the omarchy-send terminal client.

Send something from the other device and it appears as an offer in the panel; accept it and it lands in ~/Omasend. That's it.

Highlights

  • Always receiving — if the desktop is running, the box can receive. Files land in ~/Omasend, and a desktop notification tells you when they arrive.
  • Bar icon — a paper plane in the bar; it badges on unread messages and active transfers, and a click opens the panel.
  • Send anything — pick a device and press f for files or Shift+F for a whole folder (sent recursively, structure preserved), or right-click files in Nautilus → Send via Omasend to open the panel with your selection already staged.
  • Messages — LocalSend-compatible plain-text messages in both directions: compose from a device row, read in the Messages tab.
  • You stay in control — incoming offers show an accept/decline strip (auto-accept is optional), and an optional PIN gates who can send to you.
  • Finds devices anywhere — multicast discovery on the LAN, automatic Tailscale peers, and manual add-by-host/IP for everything else.
  • Scriptable — send files or messages from scripts and AI agents through the shell's IPC, no UI involved.

Requirements

Omarchy 4 with omarchy-shell — the UI is a shell plugin. On a headless or pre-quattro box the panel can't run; use the original omarchy-send terminal client there instead. Both speak the same protocol and happily talk to each other.

External dependencies: jq (already in the Omarchy base install), Go to build the engine (sudo pacman -S go), and zenity for the panel's graphical file chooser — the installer offers to add zenity if it's missing. Nothing at runtime: the engine is a single static binary with no dependencies once built.

Install details

Why there are two pieces. The UI is pure QML and loads straight into the shell. The LocalSend protocol work — discovery, HTTPS transfers, PIN — lives in omasend-engine, a small Go daemon, because the shell can't load native code. omarchy plugin add installs the QML; the engine is a separate binary, so bin/omasend-setup places it.

Where the engine comes from. bin/omasend-setup ships inside the plugin and builds ./cmd/omasend-engine from the source beside it. Nothing is downloaded, so the running binary is precisely the commit you installed, and you can audit it without leaving the directory.

That needs Go. Without it the script stops and says so rather than quietly fetching something prebuilt. If you'd rather not install a toolchain, you can opt in explicitly:

OMASEND_ALLOW_PREBUILT=1 bin/omasend-setup

That downloads the release pinned in manifest.json — never latest — and installs it only if the SHA-256 matches engine/SHA256SUMS, committed in this repo; a mismatch aborts and installs nothing. It's off by default because a prebuilt binary can't be checked against the source in front of you, however well pinned it is.

Overrides: BIN_DIR=… puts the engine somewhere else, OMASEND_REPO=user/repo uses a fork's releases. bin/omasend-setup --check reports what's installed without changing anything.

What install.sh adds. Everything above plus the optional desktop extras: the bar icon, the Nautilus right-click entry (copied from the checkout), and zenity if it's missing (asks for sudo) — the graphical chooser behind the panel's "Send file/folder" buttons; without it they fall back to a typed-path prompt. It's safe to re-run, and omarchy plugin update keeps the plugin itself current.

Coming from omarchy-send? Your identity survives: the first run migrates ~/.config/omarchy-send/config.json — alias, PIN, receive folder and the TLS certificate — so devices that already paired with you stay paired. The old TUI and Omasend can't run at the same time on one machine (both need port 53317).

Using it

Click the paper plane in the bar, or from a terminal:

omarchy-shell shell toggle nosignal.omasend

The panel is fully keyboard-driven:

Key Action
↑ ↓ / j k Move through the list
Enter / m Message the selected device (sends staged items instead, if any are staged)
f / Shift+F Pick files / a folder to send to the selected device
+ Add a remote device by host or IP
a / d Accept / decline an incoming offer
x Clear staged items
1–4 / Tab Switch tabs
Esc / q Close the panel

Every row also works with the mouse — the icons on a device row send a message, files, or a folder directly. A single click only selects a device; double-click it to send whatever you have staged (or to open a message when nothing is staged).

Receiving

Anything sent to you lands in ~/Omasend. Files still on their way carry a .part suffix until they're complete. With auto-accept off (the default), each incoming batch shows an offer strip at the top of the panel — accept or decline it; unattended offers simply expire. Flip Auto-accept in Settings if you'd rather everything just arrives.

Set a PIN in Settings and senders must enter it before anything reaches you — the same PIN mechanism the official LocalSend apps use.

Files arriving but no notification? Check Do Not Disturb — with DND on, the shell still accepts every notification and files it into history, it just never shows one, so arrivals land silently in ~/Omasend. Run omarchy-shell notifications dndState to check, setDnd off to turn it off, and showHistory to replay what you missed.

Messages

Incoming messages raise a notification and badge the bar icon; the Messages tab keeps the recent conversation (messages live in the panel, not on disk). Press Enter on a device to reply.

Transfers

The Transfers tab shows live progress for everything moving in either direction. Dismiss finished rows individually, or press c to clear all finished transfers.

Right-click in Nautilus

Select files or folders in Nautilus, right-click → Send via Omasend. The panel opens with your selection staged — pick a device, press Enter, done.

Remote devices

Multicast discovery only reaches your own LAN. For everything else: online Tailscale peers are discovered automatically when Tailscale is running, and + adds any device by host or IP, remembered for next time.

From scripts and agents

The shell exposes Omasend over IPC, so anything on the box can send without a UI or a TTY:

omarchy-shell omasend send "phone" "on my way"          # message
omarchy-shell omasend sendFile "phone" "/path/to/file"  # file or folder
omarchy-shell omasend status                            # engine health

Sends are queued and delivered asynchronously; a failure raises a desktop notification.

If you want AI agents on the machine to know all of that without being told each time, the installer can write the same summary into ~/.claude/CLAUDE.md as a marker-delimited block. That file is your standing instructions to your own agents, so Omasend never edits it uninvited — it is off unless you ask:

bash install.sh --agent-context

Run from a terminal without that flag, the installer asks once and takes no for an answer; piped or scripted, it simply skips it. --no-agent-context declines without being asked.

Troubleshooting

No paper-plane icon in the bar. The icon is a bar-layout entry in ~/.config/omarchy/shell.json, separate from the entry that makes the panel loadable — so the panel can open perfectly while no icon shows. Ask the shell, not the bar:

omarchy plugin list | grep nosignal.omasend

For a bar widget, disabled there means "has no place in the bar", whatever the panel is doing. Enabling again won't fix it: omarchy plugin enable places the widget only when the plugin is referenced nowhere in shell.json, and opening the panel leaves a reference of its own. Clear it first:

omarchy plugin disable nosignal.omasend
omarchy plugin enable nosignal.omasend right

Re-running bin/omasend-setup does exactly that for you, and leaves an icon you have already positioned where it is.

"Send file/folder" does nothing. The GTK chooser needs zenity, which isn't in the Omarchy base install: sudo pacman -S zenity. No shell restart needed — the panel re-checks on the next attempt.

Under the hood

Two parts: a pure-QML shell plugin (bar widget, panel, service) and omasend-engine, a small Go daemon that speaks the LocalSend protocol — discovery, HTTPS transfers, PIN, the lot. The shell starts and supervises the engine and talks to it over a local socket; nothing listens beyond LocalSend's standard port 53317 (TCP + UDP). Configuration lives in ~/.config/omasend/config.json. If you run a firewall, allow 53317 for both TCP and UDP on your LAN.

What it installs and writes

Everything lands under your home directory — nothing is written system-wide. omarchy plugin add writes only the first two rows; the rest arrive when you set up the engine, run install.sh, or start receiving:

Path What goes there
~/.config/omarchy/plugins/nosignal.omasend/ the plugin itself, cloned by omarchy plugin add
~/.config/omarchy/shell.json a plugins[] entry and a bar-layout entry, so the icon and panel load
~/.local/bin/omasend-engine the transfer engine, placed by bin/omasend-setup
~/.config/omasend/config.json your alias, PIN, receive folder, known remotes and TLS certificate
~/Omasend/ received files (configurable in Settings)
~/.local/share/icons/hicolor/scalable/apps/ the paper-plane icon
~/.local/share/nautilus-python/extensions/omasend.py the "Send via Omasend" right-click entry
~/.claude/CLAUDE.md opt-in only — a delimited managed block telling AI agents how to send from scripts, written solely if you pass --agent-context or accept the installer's prompt

Two of those are edits to files you may already own, so to be explicit about them. The shell.json entries are added with jq and leave the rest of the file untouched (the plugin re-adds its own plugins[] reference on first open if the shell dropped it — without that, removing the bar icon would kill the panel too). ~/.claude/CLAUDE.md is the one file Omasend will not touch on its own: it holds your instructions to your own agents, so the block is written only when you opt in with --agent-context or say yes to the prompt, and even then it sits between <!-- BEGIN omasend --> / <!-- END omasend --> markers so re-running the installer replaces that block and nothing around it. Neither file is overwritten wholesale.

The one privileged step is installing zenity — sudo pacman -S zenity, only if it isn't already present, and it's non-fatal if you decline. The engine listens on LocalSend's standard port 53317 (TCP + UDP) whenever the shell is running; that's the whole point of always-on receiving, and it's the only network listener.

Uninstall

omarchy plugin remove nosignal.omasend
rm ~/.local/bin/omasend-engine
rm ~/.local/share/nautilus-python/extensions/omasend.py
rm ~/.local/share/icons/hicolor/scalable/apps/omasend.svg
rm -rf ~/.config/omasend            # alias, PIN, pairing certificate

That leaves received files in ~/Omasend alone. If you opted into the agent block, the one in ~/.claude/CLAUDE.md is delimited by its BEGIN/END markers so you can delete it by hand.

License

MIT — see LICENSE. Omasend is an independent project, not affiliated with or endorsed by LocalSend; it merely speaks the same protocol.