Omahub
← All plugins
D

Parcel

by Daniel Zuccon

Your Parcel app deliveries in the Omarchy bar: a status-tinted badge, active shipments with ETAs, event timelines, and desktop notifications when a parcel moves.

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
29f27e4
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

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
29f27e4
Reviewed
1 month ago

This is a well-engineered, security-conscious plugin that reads parcel delivery data from the Parcel API. The code demonstrates strong security practices: API keys are stored in the system keyring and passed via stdin rather than command-line arguments, network requests are restricted to HTTPS with a hardcoded endpoint, and the code includes thoughtful defenses against symlink attacks, path traversal, and untrusted remote data. The deterministic scan found no issues, and my review of the source confirms the code matches its documentation.

  • The plugin requires a Parcel Premium API key, which is a third-party credential that will be stored in the system keyring — standard practice, but users should be aware the plugin does make network requests to api.parcel.app.
  • The full bin/parcel-api bash script was not fully visible in the sample, but the portions reviewed show careful handling of the API key and state directory security.
  • The plugin caches delivery data in ~/.local/state/omarchy/parcel/ with mode 0600, which is appropriate for potentially sensitive delivery information.
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/zuccs/omarchy-parcel-app --enable
Widgets #bar #quickshell

Parcel for Omarchy

Your Parcel deliveries in the Omarchy bar.

Parcel panel showing three deliveries with an expanded checkpoint timeline

A bar badge shows how many parcels are on the way and lights up when one is out for delivery (or needs attention). Click it for a panel listing every active shipment with carrier, latest checkpoint and ETA; expand a row for the full timeline. When a parcel changes state you get a desktop notification.

Parcel is the iOS/macOS tracking app most of us already have on our phone. This plugin doesn't replace it — it reads the deliveries you've already added there through Parcel's Premium API, so your desktop and your phone agree.

Requires Omarchy Quattro (omarchy-shell) and a Parcel Premium subscription — the API is a Premium feature. External dependencies are all part of a stock Omarchy install: curl, jq, secret-tool (libsecret), wl-copy (wl-clipboard) and flock (util-linux). No sudo, no packages to install, no changes to your configuration beyond the plugin's own entry in shell.json that omarchy plugin enable writes.

Install

omarchy plugin add https://github.com/zuccs/omarchy-parcel-app.git --enable

The widget lands in the right section of the bar. Move it with omarchy bar move.

Setup

  1. Sign in at web.parcelapp.net and generate an API key (Settings → API).

  2. Store it in your login keyring. secret-tool prompts for the value so it never touches your shell history:

    secret-tool store --label='Parcel API key' service omarchy-parcel key api-key
    
  3. Press r in the panel (or middle-click the badge). Until a key is stored the panel shows these same instructions with a copy button.

Verify from a terminal any time:

~/.config/omarchy/plugins/io.github.zuccs.parcel/bin/parcel-api status
~/.config/omarchy/plugins/io.github.zuccs.parcel/bin/parcel-api deliveries active | jq

Using it

Where Action
Badge — left click Open / close the panel
Badge — middle click Refresh now
Badge — right click Open web.parcelapp.net
Panel — ↑ ↓ / j k Move between deliveries
Panel — Enter / Space / click Expand the checkpoint timeline
Panel — y or c Copy the tracking number
Panel — r Refresh now
Panel — o Open web.parcelapp.net
Panel — Tab / Shift+Tab Switch to the neighbouring bar panel
Panel — Esc Close

Bind a key in ~/.config/hypr/bindings.lua:

o.bind("SUPER + CTRL + SHIFT + P", "Parcel", "omarchy-shell shell toggle io.github.zuccs.parcel")

Uninstall

omarchy plugin remove io.github.zuccs.parcel

That removes the plugin directory and its shell.json entry. Two things are yours and are left alone; clear them if you want a clean slate:

secret-tool clear service omarchy-parcel key api-key   # the API key in your keyring
rm -rf ~/.local/state/omarchy/parcel                    # cached deliveries

If you added a keybind in ~/.config/hypr/bindings.lua, delete that line too.

Settings

Settings live inline on the widget's entry in ~/.config/omarchy/shell.json, like every Omarchy bar widget. The defaults:

{ "id": "io.github.zuccs.parcel", "refreshIntervalSec": 600, "filterMode": "active", "notifications": "On", "hideWhenEmpty": "Off" }
Key Values Meaning
refreshIntervalSec 300–3600 How often to poll. Floor is 300 s: Parcel allows 20 requests/hour and manual refreshes count.
filterMode active / recent active shows parcels in progress; recent also includes recently delivered ones.
notifications On / Off Desktop notification when a parcel changes state (e.g. goes out for delivery, or is delivered).
hideWhenEmpty On / Off Hide the badge entirely when nothing is on the way.

How it behaves

  • Rate limits. The last good response is cached in ~/.local/state/omarchy/parcel/ (mode 0600). Opening the panel or restarting the shell reads the cache; only the timer and explicit refreshes hit the API. If Parcel returns 429 or the network is down, the cached data stays on screen with an "Offline — showing data from …" note.
  • Several monitors, one request. Each monitor's bar hosts its own copy of the widget; the bridge serialises them with flock, so they share one fetch and one set of notifications.
  • Notifications compare consecutive fetches: a parcel changing status is reported; a parcel that drops out of the list is reported as no longer active (Parcel's feed doesn't say whether it was delivered or removed — use filterMode: "recent" if you want explicit Delivered transitions); a parcel seen for the first time is not reported (your phone already told you).
  • Theme-native. Colours, fonts, spacing and corner radius come from the shell's theme tokens, so it matches whatever Omarchy theme you switch to.

Privacy & security

  • The only network endpoint is https://api.parcel.app. The only file written is the response cache above.
  • Your API key lives in the login keyring (libsecret). It is never written to shell.json, the QML never reads it, and bin/parcel-api hands it to curl as a config on stdin (-K -) rather than as an argument, so it doesn't show up in the process list either.
  • Everything the API returns is treated as untrusted — it is relayed from carrier systems, not written by Parcel. Response bodies are capped at 1 MiB before anything parses them, delivery and event lists are capped before they reach the panel, and every remote string is flattened to one bounded line of plain text. Every Text in the panel is pinned to Text.PlainText, so no delivery description can turn into rich text and pull in a remote image.
  • The state directory sits at a predictable path, so the bridge treats it as hostile: it refuses to use it if omarchy/ or parcel/ is a symlink, takes its cross-monitor lock on the directory itself (there is no lock file to plant), writes caches only via rename(2), and reads them with a size cap and a timeout so a swapped-in FIFO or oversized file can't wedge the shell. A same-user process that races a cache swap between check and read can still make the bridge read a file — bounded, and a file that process could already read itself.
  • bin/parcel-api is ~425 lines of bash. Read it before you enable the plugin, as with any Omarchy plugin.

Development

# Install the normal way — the result is a plain git checkout you can edit in place.
omarchy plugin add https://github.com/zuccs/omarchy-parcel-app.git --enable
cd ~/.config/omarchy/plugins/io.github.zuccs.parcel

omarchy plugin validate .
qmllint -I "$OMARCHY_PATH/shell" *.qml   # note: qmllint 1.0 rejects `function x(): void`, as it does on first-party Weather
node --test test/*.test.js           # Model.js is plain JS and unit-tested
PARCEL_API_KEY=… bin/parcel-api deliveries active --max-age 0 | jq   # bridge without a keyring

Saving files under ~/.config/omarchy/plugins/ hot-reloads most plugin kinds, but bar-widget QML is currently cached until the shell restarts (basecamp/omarchy#8555) — run omarchy-restart-shell after editing BarWidget.qml or Panel.qml.

Layout:

manifest.json     plugin identity, settings schema and defaults
BarWidget.qml     bar entry point: badge + Loader for the panel
Panel.qml         popup: fetch lifecycle, notifications, keyboard list
Model.js          pure functions (parsing, sorting, ETA/relative time, diffs)
bin/parcel-api    the only code that touches the network or the API key
data/carriers.json  bundled carrier code → name snapshot; `bin/parcel-api carriers --refresh`
                  caches a newer list in ~/.local/state/omarchy/parcel/, which the widget
                  prefers on its next shell start
test/             node:test suite for Model.js

Roadmap

  • Add a delivery from the panel: paste a tracking number, pick the carrier, done (bin/parcel-api add already exists — Parcel allows 20 adds/day).
  • Optional Parcel-style route map for the expanded row.

License

MIT — see LICENSE. Not affiliated with Parcel or Omarchy.