Daemon (scripts/ocd-waybar) polls {
"schema_version": 1,
"generated_at": "2026-07-30T01:29:37.918330160+00:00",
"accounts": [
{
"account": "legal",
"workspace": "wrk_01KBJFEAZV7G2FJBE1KAPRQSJN",
"fetched_at": "2026-07-30T01:27:49.014903087+00:00",
"status": "cached",
"limits": {
"usage_5h": {
"used": 0.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-07-30T06:27:49.014903087+00:00",
"status": "ok"
},
"usage_week": {
"used": 88.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-03T00:00:01.014903087+00:00",
"status": "ok"
},
"usage_month": {
"used": 94.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-21T22:07:23.014903087+00:00",
"status": "ok"
},
"next_update": null
},
"balance": {
"remaining": 0.0,
"unit": "$"
}
},
{
"account": "legal2",
"workspace": "wrk_01KQHV4ZP2SHZHTCTF0HW1BKHA",
"fetched_at": "2026-07-30T01:27:49.920803926+00:00",
"status": "cached",
"limits": {
"usage_5h": {
"used": 0.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-07-30T06:27:49.920803926+00:00",
"status": "ok"
},
"usage_week": {
"used": 100.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-03T00:00:00.920803926+00:00",
"status": "rate-limited"
},
"usage_month": {
"used": 90.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-23T18:01:33.920803926+00:00",
"status": "ok"
},
"next_update": null
},
"balance": {
"remaining": 0.0,
"unit": "$"
}
},
{
"account": "kllr560",
"workspace": "wrk_01KYJ5B4PM2EGR16ZDC0JTH2CC",
"fetched_at": "2026-07-30T01:27:50.791975864+00:00",
"status": "cached",
"limits": {
"usage_5h": {
"used": 0.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-07-30T06:27:50.791975864+00:00",
"status": "ok"
},
"usage_week": {
"used": 79.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-03T00:00:00.791975864+00:00",
"status": "ok"
},
"usage_month": {
"used": 39.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-27T16:10:15.791975864+00:00",
"status": "ok"
},
"next_update": null
},
"balance": {
"remaining": 0.0,
"unit": "$"
}
},
{
"account": "pj-vendee",
"workspace": "wrk_01KYNGQCX4XEM0KD3PWVVE636D",
"fetched_at": "2026-07-30T01:27:51.638144968+00:00",
"status": "cached",
"limits": {
"usage_5h": {
"used": 0.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-07-30T06:27:51.638144968+00:00",
"status": "ok"
},
"usage_week": {
"used": 40.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-03T00:00:00.638144968+00:00",
"status": "ok"
},
"usage_month": {
"used": 20.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-29T01:09:27.638144968+00:00",
"status": "ok"
},
"next_update": null
},
"balance": {
"remaining": 0.0,
"unit": "$"
}
},
{
"account": "iyaunalunarovell",
"workspace": "wrk_01KYNTSGXF7GFXMAMT36N3GH21",
"fetched_at": "2026-07-30T01:27:52.584601387+00:00",
"status": "cached",
"limits": {
"usage_5h": {
"used": 94.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-07-30T02:27:25.584601387+00:00",
"status": "ok"
},
"usage_week": {
"used": 99.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-03T00:00:00.584601387+00:00",
"status": "ok"
},
"usage_month": {
"used": 49.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-29T02:22:06.584601387+00:00",
"status": "ok"
},
"next_update": null
},
"balance": {
"remaining": 0.0,
"unit": "$"
}
},
{
"account": "balensiefenpiwihu2906",
"workspace": "wrk_01KYQNFP718WP7X9W7RXC2Q133",
"fetched_at": "2026-07-30T01:27:53.457572405+00:00",
"status": "cached",
"limits": {
"usage_5h": {
"used": 53.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-07-30T03:43:22.457572405+00:00",
"status": "ok"
},
"usage_week": {
"used": 21.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-03T00:00:00.457572405+00:00",
"status": "ok"
},
"usage_month": {
"used": 10.0,
"total": 100.0,
"unit": "%",
"resets_at": "2026-08-29T19:27:31.457572405+00:00",
"status": "ok"
},
"next_update": null
},
"balance": {
"remaining": 0.0,
"unit": "$"
}
}
]
} every 30s (no force
flags, so ocd cache/TTL stays in charge), runs a 5s account rotation
in config order, and supports right-click 1h lock. The waybar
custom/ocd module reads a state.json written by the daemon; hover
shows all accounts via the native tooltip. Bars are Pango background
spans (~50px) in the label and plain block chars in the tooltip, since
waybar 0.15.0 renders custom tooltips as plain text.
4.7 KiB
ocpway — waybar plugin for ocd
A waybar module that shows opencode usage limits and balance from the
ocd dashboard binary. It rotates through the accounts in your ocd
config, one every 5 seconds. Left-click advances at once. Right-click
locks the current account for one hour. Hover the bar to see all
accounts at once.
What it shows
One line per account:
kllr560 [0%/5h] ▓░░░░░░ 4:59 [79%/1w] █████▌░ 3d 22h [39%/1m] ██▋░░░░ 28d $0.00 / 1m ago
- Account name, and a lock emoji
🔒while locked. - Three bars: the 5-hour, weekly, and monthly usage window.
- The label holds the used value with its unit, e.g.
[79%/1w]. - The bar is the percentage, drawn as filled cells up to the value.
- The text after the bar is the time until the window resets.
- The label holds the used value with its unit, e.g.
- The balance and the age of the last data fetch:
$0.00 / 1m ago.
When locked, the bar cells lock to blue and the line starts with 🔒.
The hover tooltip lists every account the same way. The active row is
marked with ▸, and the lock emoji shows only on the locked row.
Design decisions
The bar is rectangular. It uses Pango background spans over non-breaking
space cells. Seven cells are about 50 px at a normal bar font. The bar in
the tooltip uses plain block characters because waybar 0.15.0 renders the
custom-module tooltip as plain text. If your waybar gains Pango markup in
custom tooltips (see Waybar PR #5034), set TOOLTIP_MARKUP = True in the
daemon to get colored background-span bars in the tooltip too.
The daemon polls ocd raw json every 30 seconds. It sends no
--force-refresh or --no-cache flags, so ocd keeps full control of
politeness: its own cache, TTL, concurrency, and pacing stay in charge.
Most polls read the cache and never touch the network. The daemon also
polls at once waybar starts
waybar 0.15.0 has no on-hover event for custom modules, so the
all-accounts view is the native tooltip, not a separate floating window.
Layout
ocpway/
scripts/
ocd-waybar the daemon (python)
ocd-waybar-ctl the click helper (sh) for advance / lock / poll / quit
config/
waybar-config.jsonc the "custom/ocd" module block to add
waybar-style.css the CSS to append
hypr-autostart.conf the exec-once line to start the daemon
README.md
Install
Copy the scripts and wiring them into your own config.
-
Copy the scripts:
mkdir -p ~/.config/waybar/scripts cp scripts/ocd-waybar scripts/ocd-waybar-ctl ~/.config/waybar/scripts/ chmod +x ~/.config/waybar/scripts/ocd-waybar{,-ctl} -
Add the
custom/ocdmodule to~/.config/waybar/config.jsonc. Seeconfig/waybar-config.jsoncfor the block and where the module name goes inmodules-right. -
Append the CSS in
config/waybar-style.cssto~/.config/waybar/style.css. -
Add the
exec-onceline inconfig/hypr-autostart.confto~/.config/hypr/autostart.conf. -
Restart waybar, and start the daemon:
pkill -x waybar; waybar & ~/.config/waybar/scripts/ocd-waybar &On later logins, the
exec-onceline starts the daemon for you.
Usage
- Hover the module: see all accounts.
- Left-click: advance to the next account at once (resets the 5-second timer).
- Right-click: lock the current account for one hour.
ocd-waybar-ctl commands
| Command | Effect |
|---|---|
| advance | Reset the timer and move to the next account. |
| lock | Freeze the current account for one hour. |
| poll | Run an ocd poll now (still respects ocd cache and TTL). |
| quit | Stop the daemon. |
The helper tries socat, then nc -U -u, then a small python fallback.
Tunables
At the top of scripts/ocd-waybar:
| Name | Default | Meaning |
|---|---|---|
ROTATE_SECS |
5 | Auto-advance cadence. |
LOCK_SECS |
3600 | One hour lock duration. |
POLL_SECS |
30 | ocd re-poll cadence. |
BAR_WIDTH |
7 | Bar cells, about 50 px. |
TOOLTIP_MARKUP |
False | Set True if your waybar renders Pango in custom tooltips. |
C_OK / C_WARN / C_CRIT / C_LOCK / C_TRACK |
see source | Zone colors. |
OCD_BIN |
ocd |
Path to the ocd binary (or set the OCD_BIN env var). |
Zone thresholds: under 70 percent is green, 70 to 90 is amber, over 90 or a
rate-limited frame status is red.
Dependencies
ocd, built and onPATH(or pointed at withOCD_BIN).python3(the daemon). Standard library only.waybar. Tested on 0.15.0.- For clicks:
socatis preferred,ncis a fallback, else the python fallback runs.
State
The daemon writes ~/.local/state/ocd-waybar/state.json. The waybar module
reads that file once per second with cat and emits it as a JSON object.
The socket lives at $XDG_RUNTIME_DIR/ocd-waybar.sock.