One screen to run your whole Hermes day.
Hermes Day is a full-screen desktop plugin for Hermes Agent that turns scattered per-session prompts into a single triage surface: an inbox for everything your agents need from you, plus a live view of what they're doing, what they finished, and what's scheduled next.
| Section | Contents |
|---|---|
| Needs you | Every open approval, clarify question, and input prompt across all sessions, profiles, bots, and remote connections, oldest first. |
| Waiting on input | Live sessions parked on a prompt this surface can't answer (e.g. delivered to another client). |
| In flight | Sessions actively working or streaming, newest activity first. |
| Finished: review | Turns that completed (or errored) while you weren't looking. They persist until you review or dismiss them. |
| Scheduled | Every cron job across sources: next run, overdue and last-failure badges. |
| Sources | Health of every profile/connection the inbox is scanning, with a per-source mute bell for the noisy ones. |
| Watching | Pin any session to keep it on the rail, running or finished, until you unpin it. |
The header carries a live day arc (a sun tracking 6 am–6 pm), a time-of-day tint, and a stat strip. Below it, four clickable stat tiles (waiting, in flight, to review, scheduled) scroll you to their section. The rail ends with a digest line: today, finished, triaged.
Cards are kind-tinted (a subtle gradient keyed to approval / question / input), lift on hover, and commands render in a dark terminal block. The board reads like a cockpit, not a list.
Focus mode (eye icon) collapses everything except what's waiting on you and what's running: the rail, the review queue, and the waiting section fold away.
When anything needs you, the board is fully keyboard-driven. The selected card shows its own key legend:
| Key | Action |
|---|---|
j / k or ↓ / ↑ |
Move selection |
a |
Allow once (approvals) |
d |
Deny (approvals) |
s |
Snooze 15 min |
o / Enter |
Open the session |
Clearing the last need triggers a small celebration. Inbox zero should feel good. A filter field above the board narrows every queue by title, preview, or method.
Cards that sit unanswered for 10+ minutes start breathing (a slow red ring pulse) and the oldest open item wears a "waiting longest" flame chip. The board nags you where your attention is most overdue.
The repo is now a dual-half plugin: __init__.py registers backend hooks next
to the desktop surface:
| Piece | What it does |
|---|---|
Completion gate (pre_verify) |
When a session edited files and tries to finish without a passing test/check run, the turn is nudged back to produce real evidence (self-throttled inside the framework's verify budget). |
Honesty guard (pre_tool_call) |
Vetoes tool calls that fake a pass: deleting/reverting/truncating test files, in-place sed on tests, gutting assertions via file edits, --passWithNoTests-style flags, ` |
Evidence badges (/day-evidence + post_tool_call) |
Finished rows in the cockpit carry a verdict chip: verified (exit 0), no evidence, checks failed, or guard ×N when the agent tried to cheat. |
No LLM in the loop; every check is deterministic.
- Quick-task bar: type what you want done, hit Enter: the plugin creates the session and submits the prompt without leaving the board.
- Saved prompt presets: one-click chips under the bar (defaults included); add your own with “save a prompt”, remove with ×.
- Clear all reviewed: one button empties the review queue.
- Desktop notifications: new needs announce themselves via the OS (bell toggle in the header; the first scan never fires, so no notification storm on launch).
- Snooze & mute: snooze a card for 15 minutes, or mute a whole source; hidden items stay out of the counts until they're due.
- Flood bar: when one session stacks up multiple approvals, a single "Allow all" bar clears them in one click via
approval.respond { all: true }. - Snooze presets: 15 min, 1 hour, or tomorrow 9 am from the card's clock menu.
- Pin to Watching: keep an eye on any session; pinned rows live in the rail until you release them.
- Undo dismiss: dismissing a finished item pops a 6-second undo chip at the bottom of the board.
- Approvals: Allow once / Allow session / Always / Deny inline, honoring the backend's choice set (
allow_permanent,smart_denied, customchoices). - Clarifies: Choice buttons, free-text answers, and multi-question batches answered per-question via
clarify.lock. - Privileged prompts (
sudo,secret,vault,mcp_setup): jump straight to the owning session; secrets stay typed into the session's masked input. - Reply to a session: running, waiting, and finished rows take an inline follow-up prompt (
prompt.submit); no need to open the session to steer it. - Stop a runaway: in-flight rows carry a stop button wired to
session.interrupt. - Heartbeat sparkline: every in-flight row draws a live sparkline of its event throughput (delta of
latest_seqbetween polls), so you can see a stall before you open it. - Every row deep-links into its session through the owning connection/profile route (
host.openSessionwith a storedroutedescriptor).
- Full-screen
/daypage: sidebar nav entry ("Day") plus aROUTES_AREAroute. - Statusbar chip: live count of items waiting on you; click to open Day.
- Command palette: "Open Day" (
hermes-day.open) and "Day: Toggle notifications" (hermes-day.notify). - Keybind:
Mod+Shift+I(rebindable in Settings → Keyboard).
Pure renderer plugin: no agent half, no credentials, no config. It polls the gateway's own contracts:
host.profileRoutes()→ every reachable connection/profilesession.active_list→ live sessions per sourcesession.events.since { last_seen: MAX_SAFE_INTEGER }→ each session'sopen_requestssnapshot without replaying eventsrequest.answer/approval.respond/clarify.lock→ the same answer paths the in-session cards usecron.manage { action: 'list' }→ scheduled jobsctx.onEvent('message.complete' | 'error')→ the review list, persisted inctx.storage
Finished items also light the sidebar's own unread dot via markSessionUnreadFinished, and reviewing clears it with ackStoredSessionId; the plugin borrows core's attention store instead of keeping a parallel one.
hermes://plugin/install?repo=DECRUX9812/hermes-day&enable=1
Or clone the desktop/ half for hot-reload development:
mkdir -p ~/.hermes/desktop-plugins/hermes-day
cp desktop/plugin.js ~/.hermes/desktop-plugins/hermes-day/plugin.js
# toggle on under Settings → Capabilities → PluginsEdit desktop/plugin.js on disk; the desktop runtime watches
~/.hermes/desktop-plugins/<id>/plugin.js and hot-reloads on save. The plugin
is a single self-contained ESM file: plain jsx()/jsxs() calls, imports
limited to @hermes/plugin-sdk, react, and react/jsx-runtime, matching
the catalog's desktop-surface lint.
MIT