Blog: Product

Open Voice Shield in the Omarchy bar

By the TelecomsXChange engineering team ·

Open Voice Shield now runs in the Omarchy bar. A shield glyph sits with your clock and your battery: quiet while nothing is wrong, badged the moment a high-risk verdict lands. Click it for the calls up on your trunk right now, the week's traffic, the latest verdicts, and a test call you can place down a route without opening a browser. It is open source, MIT, and published in the official Omarchy plugin directory.

Why a fraud feed belongs on the bar

Open Voice Shield already tells you when something is wrong. A verdict lands in your inbox, in your Slack channel, on your webhook endpoint. That works when you are away from the desk. At the desk, an alert you have already dismissed is not a dashboard, and a browser tab you closed on Monday is not a monitor.

Omarchy is an opinionated Arch and Hyprland desktop by DHH, and it has a bar that is part of the shell, the same one that draws the menu, the notifications and the lock screen. NOC engineers, carrier ops people and the kind of developer who runs a SIP stack for a living already live on one. So the plugin puts the account where the clock is.

What is on the bar

The pill is a shield glyph. While nothing is wrong it shows the number of calls currently up, or nothing at all. When a verdict at or above your threshold lands, it badges today's high-risk count in the theme's urgent colour. Hovering gives you the summary; clicking opens the panel. It sits in whichever section of the bar you put it in, and it takes the theme it finds there.

The plugin open under the Omarchy bar. The bar pill badges 8 high-risk verdicts today. The panel below shows 431 calls today with 3 active on 48 ports, a low/medium/high risk split, a week of volume with high-risk counts on their own strip, calls and minutes against spend and balance, three live calls with their state, route prefix and transport, and four recent verdicts with their probability and recommendation. Every phone number is masked.
The pill badges the day's high-risk count and the panel carries the rest. Note the numbers: masked by default, country code and route prefix left readable. Demo data, and the numbers are from the ranges reserved for fiction.
The panel, top to bottom.
SectionWhat it answers
Hero Calls today, active calls, ports, high-risk count.
Risk distribution The low, medium and high split across your reporting window.
Volume and high risk Seven days of call volume, with high-risk counts on their own scale.
Stats Calls, minutes, high-risk rate, spend, balance, ports in use.
On the wire A card per live call: ringing or connected, a clock counting up between fetches, the route prefix and transport, and progress toward the per-call cap.
Recent verdicts Probability, title, route, age and recommendation. Enter opens the call in the browser.
Test call Dial a number down a route and watch the result arrive.

What it takes to leave this on a screen

A bar widget is different from a dashboard in two ways that matter. It is always visible, including to everyone in your screen share. And it is one click from everything else you do, including the clicks you did not mean. Both shaped the plugin more than the feature list did.

Numbers are masked by default

Phone numbers render as +97144••••11. The country code and the route prefix stay readable, because those are what you are diagnosing. The subscriber digits do not, because a panel that is on screen during a demo, a screenshot or a walk past your desk should not be leaking the numbers your customers called. Full numbers are one setting away, and the setting is opt-in rather than opt-out.

Dialling takes two presses

The first press arms the button, which turns urgent and reads Confirm. The second places the call. The arming lapses after five seconds, and editing the number or changing the route disarms it. A stray click in a bar panel should not put a call on a stranger's phone and a charge on the account, so it cannot. Before any of that, the composer names the route, the sample and the length, and says that calls are billed per second.

If the platform's monitor reports the chosen route as down, the composer says so before you spend a call finding out. And on a shared or kiosk desktop the whole dialer comes out: set testCalls to false and the composer is gone.

The number never reaches the process table

The dialled number is handed to the helper in its environment rather than its arguments. On Linux /proc/PID/cmdline is world-readable and /proc/PID/environ is not, so a number someone is calling is not something to hand to every other process on the machine. The API key is read from its config file for the same reason, and never appears on a command line.

A failure shows its reason on the panel

The fetch helper always exits zero. When something is wrong it says so in its JSON: no key, unreachable, a missing dependency. The panel renders that as a reason you can act on, instead of a widget that quietly stops updating and lies to you by showing yesterday's numbers as though they were live. A transient failure keeps the last good reading on screen and says when it was taken.

Notifications prime rather than replay. The first fetch after a shell start only records what it has seen, so restarting your desktop never dumps a backlog of verdicts on you as a burst of critical notifications. After that, a new verdict at or above your threshold raises one, with the route, the probability and the recommendation.

Two calls a minute

The steady state is two requests per refresh: one for the dashboard, one for live calls. Nothing else runs on a timer. The destination list is fetched once, the first time you open the composer. A placed test call is polled every five seconds until it reaches a terminal state, and at most 180 times, so a record that never settles is not polled forever. Everything the widget uses is in the customer REST API, so nothing here is privileged: you could build the same thing for your own bar, and the plugin is MIT licensed so you can start from this one.

One chart decision comes up whenever you put two series of very different size next to each other. High-risk calls are a small fraction of daily volume. Stacked inside the volume bar they clamp to a sliver on every day and read as an axis rather than as data. So they are drawn as two strips on independent scales, volume against the busiest day and high risk against the worst day, with nothing implying the two share an axis.

Install it

The plugin is listed in the official Omarchy plugin directory as tcxc.voice-shield, where the directory marks it verified. It installs the way any Omarchy plugin does, and needs curl and jq.

add it to the bar

omarchy plugin add https://github.com/TelecomsXChangeAPi/omarchy-voice-shield
omarchy plugin enable tcxc.voice-shield --section right

Then mint a key. In the portal, open Developers and create an API key; it starts with ovs_. If you do not have an account yet, signup takes a minute and comes with $5 of credit, which covers a good number of test calls.

store the key

mkdir -p ~/.config/omarchy
cat > ~/.config/omarchy/ovs.json <<'EOF'
{ "apiKey": "ovs_…" }
EOF
chmod 600 ~/.config/omarchy/ovs.json

The refresh interval, the reporting window, the notification threshold, number masking and whether test calls are allowed all live in the plugin's entry in shell.json, and Omarchy's own bar settings read them from the manifest. Point baseUrl at your own deployment if you run one.

The source is on GitHub. Issues and pull requests are welcome, and if you want the same thing on a different bar, the two shell helpers are about a hundred lines between them and the parsing is in a plain JavaScript module with no desktop imports.

What else is worth putting on a bar

This is the first desktop surface for Open Voice Shield and it will not be the last one. If you run a bar we have not covered, or you want something on this one that is not there yet, tell us: support@telecomsxchange.com. The rest of what people put on an Omarchy bar is in the plugin directory, where this one now lives too, and the desktop itself is at omarchy.org. The rest of the product is on the features page, and the API the plugin uses is documented at the API reference.

Questions

Frequently asked questions

What is the Open Voice Shield Omarchy plugin?

A bar widget for the Omarchy Linux desktop that shows your Open Voice Shield account on the bar: today's high-risk fraud verdicts, the calls currently up on your SIP trunk, the week's traffic, recent verdicts, and a composer for placing a test call down a route. It is open source under the MIT licence.

How do I install it?

omarchy plugin add https://github.com/TelecomsXChangeAPi/omarchy-voice-shield, then omarchy plugin enable tcxc.voice-shield --section right. It needs curl and jq. Mint an API key in the portal under Developers and write it to ~/.config/omarchy/ovs.json.

Are phone numbers shown in full?

No, not by default. Numbers are masked so the country code and route prefix stay readable and the subscriber digits do not, because a bar panel is on screen during screen shares, screenshots and over your shoulder. Full numbers are opt-in with maskNumbers set to false.

Can it place calls by accident?

Dialling takes two presses. The first arms the button, the second places the call, the arming lapses after five seconds, and editing the number or changing the route disarms it. The composer names the route and the call length and says calls are billed per second before anything is dialled. Setting testCalls to false removes the dialer entirely.

How much does the widget cost in API calls?

Two requests a minute in the steady state: one for the dashboard, one for live calls. The destination list is fetched once when the composer first opens, and a placed test call is polled every five seconds until it finishes, at most 180 times.

What happens when the API is unreachable?

The fetch helper always exits zero and returns a JSON error state, so the panel shows a diagnosable reason such as no key, unreachable or a missing dependency instead of a dead widget. A transient failure keeps the last good reading on screen.

Does it work with a self-hosted deployment?

Point baseUrl in ~/.config/omarchy/ovs.json at your own deployment's API.