Integration
Live Events
stasis watch prints the current
state immediately, then writes another JSON object only when the state, pause status, or active
profile changes. Any program that can keep a process open and read lines can use it instead of polling stasis info.
stasis watch
# {"state":"waiting","paused":false,"manually_paused":false,"profile":"default"}
# {"state":"manual","paused":true,"manually_paused":true,"profile":"work"}Each line includes state, paused, manually_paused, and profile. The state is one of waiting, active, inhibited, locked, or manual.
Blame
stasis blame explains why an idle action is held. It names active manual and
system pauses, matched applications and media, suspend-only blockers, live D-Bus inhibit
cookies or portal request handles, and login1 idle holds. Use stasis blame --json for a versioned snapshot that scripts can parse.
stasis blame
stasis blame --jsonThe JSON form uses schema_version 1. Categories include app_inhibitors, media_inhibitors, suspend_app_inhibitors, and suspend_media_inhibitors.
Live D-Bus and login1 holds are listed separately.
{
"schema_version": 1,
"generated_at_ms": 1750000000000,
"progression_blocked": true,
"manual_pause": false,
"system_pause": false,
"browser_source_capture": false,
"app_inhibitors": { "active": false, "count": 0, "sources": [] },
"media_inhibitors": { "active": false, "count": 0, "sources": [] },
"suspend_app_inhibitors": { "active": false, "count": 0, "sources": [] },
"suspend_media_inhibitors": { "active": false, "count": 0, "sources": [] },
"dbus_holds": [],
"login1_idle_holds": [
{
"status": "live",
"what": "idle",
"who": "codex",
"why": "Codex is running an active turn",
"mode": "block",
"uid": 1000,
"pid": 42,
"process": "codex",
"started_at_ms": 1749999996500,
"age_ms": 3500
}
]
}Status JSON
stasis info --json is the stable status-bar contract. The text field uses short labels: waiting, active, inhibited, locked, and manual.
The alt and class fields are intended for icon mapping and CSS styling. Tooltips include
the active profile, plan source, state, manual pause status, app/media inhibitor counts, D-Bus inhibit state,
login1 idle inhibitors that are blocking suspend, and the next pending action when available.
When one or more login1 idle holds are present, stasis info --json also includes a login1_idle_inhibitors array.
{
"text": "active",
"alt": "idle_active",
"class": "idle_active",
"tooltip": "Profile: default\nPlan Source: Desktop\nState: active",
"profile": "default"
}Waybar
Example Custom Module
To use Stasis with Waybar, define a custom module that polls stasis info --json.
Icon-based Display
"custom/stasis": {
"exec": "stasis info --json",
"format": "{icon}",
"format-icons": {
"idle_active": "",
"idle_waiting": "",
"idle_inhibited": "",
"manually_inhibited": "",
"locked": "",
"not_running": ""
},
"tooltip": true,
"on-click": "stasis toggle-inhibit",
"interval": 2,
"restart-interval": 2,
"return-type": "json"
}Text-based Display
Or display text instead of icons:
"custom/stasis": {
"exec": "stasis info --json",
"format": "{text}",
"tooltip": true,
"on-click": "stasis toggle-inhibit",
"interval": 2,
"restart-interval": 2,
"return-type": "json"
}System Tray
stasis tray runs the optional StatusNotifier tray frontend. It is separate from
the headless daemon and does not replace stasis info --json, so Waybar and other
status bars can keep polling the JSON output directly.
The tray tooltip shows the current Stasis state. Its menu provides actions to toggle
manual inhibition, pause, resume, reload the config, and quit only the tray process.
Only one tray instance is allowed per desktop session; additional launches exit cleanly.
The shell title is Stasis. The menu includes a disabled status row so hosts
such as Waybar still show the current state, including Stasis paused (manually).
Start a StatusNotifier tray host first, such as Waybar's tray module, KDE Plasma, or another panel with tray support. The daemon remains headless and does not launch the tray automatically.
Run Manually
stasis traySystemd User Service
Run the daemon and tray as separate user services. Packages may already install this
optional service file as stasis-tray.service.
[Unit]
Description=Stasis System Tray Frontend
PartOf=graphical-session.target
After=graphical-session.target stasis.service
ConditionPathExists=%t
[Service]
Type=simple
ExecStart=/usr/bin/stasis tray
Restart=on-failure
RestartSec=2
[Install]
WantedBy=graphical-session.targetNixOS and Home Manager users can enable the tray through the module option services.stasis.tray.enable.