Omahub
← All plugins
D

Sinbar

by d3vw

A keyboard-first sing-box monitor with outbound and Tailscale controls for the Omarchy bar.

Security review

Review recommended · 377 findings

Deterministic scan — not a security guarantee

Low
Risk level
Low
Analyzed commit
f6f46a6
Scanned
2 weeks ago

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

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

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

This is a legitimate, well-engineered bar widget for monitoring sing-box and controlling Tailscale. The deterministic scan's 'obfuscation' findings are false positives: the flagged `daemon/started_service.pb.go` is standard protobuf-generated code whose embedded file descriptor uses octal/hex escapes — normal for protoc output, and clearly matched by the repo's own `proto/started_service.proto`. No obfuscated logic, hidden persistence, credential theft, or destructive behavior exists in the sampled code.

  • The bootstrap script `ensure-bridge.sh` downloads a prebuilt Go bridge from GitHub Releases and verifies its SHA-256, but the checksum comes from the same release; a compromised maintainer account could distribute a malicious binary. The fallback to building from source with Go mitigates this, and the release workflow adds build-provenance attestation.
  • The plugin connects to a sing-box gRPC API using a secret from `~/.config/sinbar/config.toml` and streams status/connections/logs; this is user-configured and documented, not hidden.
  • Taildrop file handling correctly guards against path traversal (peer-controlled filenames), per the `TestUniquePathRejectsTraversal` tests.
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/d3vw/sinbar --enable
System #bar #quickshell
<div align="center">

Sinbar

Your sing-box dashboard, right in the Omarchy bar.

Live traffic · Routes · Connections · Logs · Tailscale & Taildrop

A keyboard-first plugin for the Omarchy Quattro shell.

Install · Configuration · Controls · Development

<img src="docs/screenshot-tailscale.png" alt="Sinbar Tailscale panel showing peer devices and received files" width="452">

<sub>QML + Go · Linux amd64 / arm64 · MIT licensed</sub>

</div>

At a glance

Area What you can do
Bar & status Follow download speed in a fixed-width widget; see upload/download totals, uptime, memory, and service status in the panel.
Routes Browse outbound groups, switch nodes, test latency, and change Clash mode.
Connections Find connections by domain, address, process, or route; close one or all.
Logs Follow messages in sing-box's own colors, filter by keyword, and clear logs.
Tailscale Browse peers, copy IPs, open system SSH over a peer's Tailscale IP, select or clear an Exit Node, and authenticate.
Taildrop Send files, drop them onto the bar, preview/save/discard received files, and get unread badges and desktop notifications.

Navigate with j / k, filter with /, and press ? for help. A fixed footer shows shortcuts for the current tab and focus, with unavailable actions dimmed.

Sinbar talks to sing-box through its StartedService gRPC API. Tailscale controls use that same API; a separate tailscaled service or tailscale CLI is not required.

Install

Requirements

  • Omarchy Quattro shell and a Nerd Font.
  • sing-box with the StartedService gRPC API enabled.
  • For source builds only: Go 1.25.5 or newer.
  • Optional: your own terminal TUI command for the right-click shortcut.
<details> <summary><strong>External commands and desktop services</strong></summary>
Used for Dependencies
Plugin management and rendering Omarchy Quattro, Quickshell, Qt Quick/Controls, and the shell's qs.Ui / qs.Commons imports
Repository installation Git, through omarchy plugin add
Bridge bootstrap POSIX sh, curl, sha256sum, sed, and standard Unix file utilities
Local build and validation Go, Make, qmllint, Omarchy CLI, and jq
Copying peer IPs wl-copy (wl-clipboard)
Choosing files to send omarchy-file-select, session D-Bus, and a working desktop file-chooser portal; the Omarchy helper uses Python 3 and PyGObject/Gio
Opening received files xdg-open and an associated desktop application
Tailscale authentication omarchy-launch-browser and a configured browser
System terminal and SSH omarchy launch terminal and OpenSSH; used for peer SSH and the optional right-click TUI
Desktop notifications notify-send

Sinbar connects to an existing sing-box service; it does not install, configure, or start that service. Enable its StartedService API before use. Tailscale features additionally require a configured sing-box Tailscale endpoint and authentication to your tailnet.

</details>

Add the plugin

omarchy plugin add https://github.com/d3vw/sinbar.git --enable

The plugin prepares its bridge on first launch. No separate build command is needed when a matching prebuilt binary is available.

<details> <summary><strong>How the bridge is installed and updated</strong></summary>

omarchy plugin add clones the repository; it does not run a build step. On first launch, scripts/ensure-bridge.sh:

  1. Downloads the Linux amd64 or arm64 bridge from the GitHub Release matching manifest.json.
  2. Verifies its SHA-256 checksum before installing it.
  3. Falls back to building from source if the download is unavailable and Go is installed.

Downloaded bridges are cached under $XDG_CACHE_HOME/sinbar/bridges/ (by default ~/.cache/sinbar/bridges/), outside the watched plugin directory. This prevents shell reloads while a bridge is downloading. A local installation may instead use bin/sinbar-bridge, with its version recorded in bin/.version. When a plugin update changes the manifest version, the next launch prepares the matching bridge. If an update cannot be downloaded or built, an existing local binary is kept with a warning.

</details>

From a local checkout

make install-local

This tests, validates, and builds the plugin, installs it under ~/.config/omarchy/plugins/io.github.d3vw.sinbar/, and enables the widget. Run it again after source edits to sync the installed copy.

<details> <summary><strong>Uninstall</strong></summary>
omarchy plugin remove io.github.d3vw.sinbar

From a local checkout, make uninstall-local runs the same command.

</details>

Configuration

Sinbar reads ~/.config/sinbar/config.toml. If your API uses 127.0.0.1:9999 without a secret, the defaults work without creating a file.

host = "127.0.0.1"
port = 9999
secret = "your-api-secret"
tls = false
interval_ms = 1000
tailscale_endpoint = "Tailscale"

Match these values to your sing-box API settings; omit secret if authentication is not configured.

Setting Purpose
host / port sing-box StartedService API address
secret API authentication secret, if configured
tls Enable TLS for the gRPC connection
interval_ms Status polling interval in milliseconds; default 1000
tailscale_endpoint Tailscale endpoint tag; default Tailscale

For a configuration containing a secret:

chmod 600 ~/.config/sinbar/config.toml

Bar settings

The plugin ID is io.github.d3vw.sinbar. Its default bar section is right. To place it there explicitly:

omarchy bar move io.github.d3vw.sinbar --section right
Setting Default Purpose
Config path ~/.config/sinbar/config.toml Use a different connection configuration
Show live speeds in bar On Show or hide the bar's download readout
Tailscale SSH username root Username on the remote device; change it when the remote account differs
TUI command Empty Command to open in a terminal on right click; empty disables it

Controls

Everyday navigation

Key Action
1 / 2 / 3 / 4 Routes / Connections / Logs / Tailscale
h / l Previous / next tab
j / k or ↓ / ↑ Move selection in Routes, Connections, or Tailscale
/ Filter the current section
? Toggle the full shortcut reference
m Cycle Clash mode
r Reconnect the API bridge
t Open the configured terminal TUI
Esc Dismiss help first, otherwise close the panel

Within each tab

Tab Key Action
Routes Tab / Shift+Tab Switch focus between Group and Node
Enter on Group Focus that group's nodes
Enter on Node Select the outbound
u Test the focused node's latency
Connections x / X, d, or Enter Close the selected visible connection
D Close all connections, including filtered-out rows
Logs c Clear logs
Tailscale Enter or a Open Tailscale SSH for the selected supported peer in the system terminal
s Choose files to send to the selected peer
c Copy the selected peer's first Tailscale IP

Set nodeLayout to "List" (default) or "Grid" in the Sinbar widget entry in ~/.config/omarchy/shell.json. You can also use the widget's Node layout setting. Grid displays three equal-width cards per row, with node name, type, latency, active selection, and a latency-test button. There is no layout toggle in the panel.

{ "id": "io.github.d3vw.sinbar", "nodeLayout": "Grid" }

While nodes are focused in Grid mode, h / l (or Left / Right) move between cards and j / k (or Down / Up) move by a grid row. Enter selects the node and u tests latency as before.

Routes starts with Group focused. A ▸ heading and row highlight show where j / k will move. Browsing groups previews their nodes; selecting an outbound requires Enter in Node or clicking a node. Outside Routes, Tab switches shell panels.

Tailscale highlights the current peer on hover, click, or keyboard navigation and keeps the highlight when the pointer leaves. Sending requires an online peer that can receive files. SSH opens the system ssh client against the online Linux peer's Tailscale IP, using your existing SSH keys and configuration; it does not require the Tailscale SSH service. Opening either the terminal or file chooser closes the panel first to release keyboard focus.

A badge on the bar shows unread Taildrop files. New arrivals produce a desktop notification; opening the Tailscale tab marks the inbox as read. Existing unread files do not trigger another notification merely because Sinbar or the shell restarted.

Search

Press / to filter live, Enter to confirm and return to navigation, or Esc while editing to clear the filter. Press / again to edit an existing keyword. Action shortcuts are inactive while typing.

Search is case-insensitive. Each section remembers its own keyword, including separate filters for Group and Node. Keyboard actions follow the visible selection.

Section Searchable fields
Group Group name
Node Node name and type
Connections Domain, source/destination address, process path, network type, inbound/outbound name
Logs Message text
Tailscale Peer name, DNS name, IPs, OS, and received filenames

Mouse & files

Input Action
Left click the bar widget Open or close the panel
Middle click Restart the API bridge
Right click Open the configured terminal TUI
Drop files onto the bar widget Open Tailscale to choose a recipient
Click a received file Preview it with the desktop's default application
Received-file action buttons Save to ~/Downloads or discard

Development

Use the Omarchy development guide as the authoring reference. Keep installed edits in the user plugin directory, never in $OMARCHY_PATH/shell/plugins/.

Sinbar declares one bar-widget, with entryPoints.barWidget pointing to Panel.qml. That file uses the shell's Panel base for its bar button and nested popup lifecycle; Service.qml is an internal helper, not a separately registered service plugin.

The bar and panel stay in QML; all gRPC communication runs through the Go JSON-lines bridge. High-frequency connection and log streams are active only while the panel is open.

File Responsibility
Panel.qml Bar widget, panel, and keyboard navigation
Service.qml Bridge processes, streams, and actions
Model.js Display formatting helpers
manifest.json Plugin metadata and settings schema
scripts/ensure-bridge.sh Bridge download and source-build fallback
cmd/sinbar-bridge/ Go JSON-lines bridge
client/ StartedService API client
daemon/ Generated protobuf bindings
make check          # Test, validate QML/plugin, and build
make install-local  # Also install and enable the user plugin
<details> <summary><strong>Individual checks and troubleshooting</strong></summary>
go test ./...
omarchy plugin validate "$PWD"
qmllint -I "$OMARCHY_PATH/shell" Panel.qml Service.qml

Confirm discovery and enablement:

omarchy-shell shell rescanPlugins
omarchy plugin list --json | jq '.[] | select(.id == "io.github.d3vw.sinbar")'

Exercise the shell lifecycle:

omarchy-shell shell summon io.github.d3vw.sinbar '{}'
omarchy-shell shell hide io.github.d3vw.sinbar

Before release, manually check clicks, Escape, shell open/close, disable/re-enable, restart, and removal. These are verification steps, not a claim that every scenario is covered by automated tests.

If an installed QML change does not appear, restart the shell to replace existing instances:

omarchy restart shell

Inspect shell errors:

qs log -p "$OMARCHY_PATH/shell" --tail 100

Connection errors appear in the bar tooltip; action errors appear in the panel. Reconnecting briefly stops the bridge as part of normal operation.

</details> <details> <summary><strong>Publishing a release</strong></summary>

Bump manifest.json and push a matching vX.Y.Z tag. The release workflow intentionally checks that the tag matches the manifest version, then produces Linux amd64 and arm64 bridges with .sha256 files and build-provenance attestations.

Local installation replaces the bridge atomically and writes bin/.version so the bootstrap script recognizes the locally built binary. Downloaded and fallback-built bridges are instead staged atomically in $XDG_CACHE_HOME/sinbar/bridges/, avoiding plugin-directory file changes that would trigger a Quickshell reload.

</details>

Security & privacy

Permissions and local data

Installation and normal operation use your user permissions; Sinbar has no sudo/polkit step and installs no system service or package-manager hooks. It runs inside the existing shell and starts bridge/helper processes, not a second Quickshell instance.

Location Use
~/.config/sinbar/config.toml Read connection settings and the API secret
~/.config/omarchy/plugins/io.github.d3vw.sinbar/ Installed plugin; a local source installation may also place its bridge and version stamp here
$XDG_CACHE_HOME/sinbar/bridges/ (default ~/.cache/sinbar/bridges/) Downloaded or fallback-built bridge binaries
Files chosen for sending Read and send through sing-box Taildrop
~/Downloads/ Save received files
$XDG_CACHE_HOME/sinbar/taildrop/ (default ~/.cache/sinbar/taildrop/) Stage received files for preview

Removing the plugin does not clean up the separate Sinbar configuration, preview cache, or saved downloads. Discarding a received file acts on sing-box's pending inbox.

Network and execution

Omarchy plugins run unsandboxed inside the shell process. The Go bridge reads the API secret directly from TOML; the secret is not passed through QML state or process arguments.

The bootstrap script verifies downloaded binaries against their release SHA-256 files. The release workflow also publishes build-provenance attestations, but the bootstrap script does not verify those attestations. Source builds may download Go dependencies. Runtime communication uses the configured sing-box API; file previews and the optional TUI command launch desktop applications.

License

MIT