OptionalProductivityVersion 0.2.0

Live Dashboard Skill: Self-Updating Status Pages in Hermes

Build self-updating dashboards from live sources.

Written by Neura Market from the official Hermes Agent documentation for Live Dashboard. Commands, paths, and version numbers are reproduced from the source unchanged.

Read the official documentation

The Live Dashboard skill turns a plain request into a status page that keeps itself current. You describe what you want to watch, and Hermes pins down the data contract, builds a self-contained HTML page, proves one live read works, then schedules a recurring refresh. It suits anyone who wants a single place to see where applications, deals, bugs, or shipments stand without asking for a status update every morning.

What it does

The skill handles the whole lifecycle of a dashboard, not just the first render. Setup happens once in the foreground: you and the agent agree on what the dashboard tracks, each field gets tied to a named source, and every source gets a live read before anything is scheduled. From then on, a cronjob tick re-reads the sources, diffs the results against stored state, updates the page, and only speaks up when something material changed.

Two files carry the work. dashboard.json holds the contract and the current state, including per-field values, the source each value came from, retrieval timestamps, a needs_attention list, and an append-only change log. index.html is a single self-contained page with inline CSS and no external requests, regenerated from the JSON on every refresh. The JSON is the source of truth; the HTML is a projection of it.

This is a good fit when the answer to "what is the status of X" changes over time and lives in more than one place. It is a poor fit for a one-off question, which you should just answer directly.

Before you start

You need at least one source connector that the dashboard will read from. Email and calendar can come through himalaya or google-workspace, websites through web_extract or browser_navigate, and local files through read_file. If none of these is configured, the sources have to be renegotiated during the contract step before any artifact is written. That ordering matters: a dashboard built on a source you cannot actually read will fail on an unattended run, not while you are watching.

The cronjob capability is required for the recurring tick. Without it you can still build and render a dashboard, but it will not refresh itself.

Optionally, the desktop_preview tool is available in Hermes desktop app sessions. When it is in the toolset, dashboards render in the in-app preview pane. When it is not, the user is given the file path instead. Do not assume the preview is available outside a GUI session.

The skill is optional and installed on demand. It lives at optional-skills/productivity/live-dashboard, is version 0.2.0, authored by Teknium (teknium1) at Hermes Agent, and released under the MIT license. It runs on linux, macos, and windows.

Defining the contract

Everything starts from the user's sentence. The agent pins down the dashboard's purpose in one line, the entities being tracked (the rows), the fields per entity (columns or indicators), what "needs attention" means, which source each field is read from, and the refresh cadence. Ambiguity gets asked about rather than guessed at, because a dashboard tracking the wrong grain is worthless. The step is done when every field on the dashboard names the source it will be read from.

In practice this is where most of the thinking happens. If the user says "track our visa applications," you need to know whether a row is an application or an email thread. If they say "needs attention," you need a rule, not a feeling. Getting these answers now is cheaper than rebuilding the page later.

Verifying sources with one live read

Before building anything, each source gets one bounded foreground read. Email and calendar go through the connector skills (himalaya, google-workspace), websites through web_extract or browser_navigate, and local files through read_file. Record what was actually retrievable. Auth walls, missing permissions, and empty results surface here, while you are present, rather than on the first scheduled run. Sources that fail get dropped or replaced. The step is done when every field's source returned real data or was explicitly renegotiated with the user.

This is the single most valuable habit in the skill. A scheduled job that hits an auth wall at 8am produces nothing useful and may quietly overwrite good state if you are careless about error handling.

Building the dashboard artifact

Write two files under the Hermes home directory's dashboards/<slug>/ directory. That is the same directory that holds config.yaml, and you should never assume a fixed location: resolve it from the running install.

dashboard.json holds the contract plus current state: purpose, entities, per-field values, per-field source and retrieval timestamp, a needs_attention list, and a change log that is append-only with the most recent entry first.

index.html is a single self-contained page rendering that state. It has a header with the purpose and last-updated time, a "Needs attention" section on top, the entity table, and the recent-changes list. Regenerate it from dashboard.json on every refresh. Never hand-edit HTML state.

Populate both from the reads you did in the previous step, then show the result. The step is done when the page renders the live data and every value on it carries a retrieval timestamp in dashboard.json.

Scheduling the refresh

Only schedule after the artifact step succeeded. If the daily all-dashboards sweep offered via /suggestions at install time is already scheduled and its cadence suits, it will pick this dashboard up: say so and stop. Otherwise create a per-dashboard job whose prompt names the state file:

cronjob(action="create",
        schedule=<cadence from the contract, e.g. "0 8 * * *">,
        prompt="Load the live-dashboard skill and run the refresh tick for the dashboard at <absolute path to dashboards/<slug>/dashboard.json>.",
        deliver=<user's destination>)

Pick a cadence that respects source rate limits. The step is done when a job covering this dashboard exists and its prompt names the state-file path, or the sweep covers it.

Running the tick

Each scheduled run follows three steps. First, load dashboard.json (for the sweep, every dashboards/*/dashboard.json, one at a time), re-read each field from its named source, and compute a field-level diff against stored state. A failed source read means unknown state: keep the last good value, mark the field stale with the failure time, and never overwrite good data with an error. The step is done when every field is updated, unchanged, or explicitly marked stale.

Second, apply the diff to dashboard.json: update values and timestamps, append material changes to the change log, and recompute needs_attention against the contract's attention rules. Regenerate index.html from the updated state, then show the result. Done when the JSON and HTML agree and the change log entry for this run exists, or the run is recorded as no-change.

Third, deliver on material change and stay silent otherwise. If the diff contains material changes or new needs-attention items, deliver a short summary: what changed, what needs attention, and where the dashboard is. Otherwise respond with [SILENT]. No "still watching" noise unless the user asked for a periodic digest. Done when delivery matches the diff.

Showing the dashboard

After every build or re-render, and on request, render where the user can see it. In a desktop or GUI session where desktop_preview is in the toolset, call desktop_preview(action="open", url=, label=) so the page renders live in the preview pane beside the chat, and re-open after each re-render so the pane shows the new state. In any other session, including CLI, messenger, and cron ticks without a GUI, report the absolute path of index.html and offer to open it where the platform allows. Done when the user has either seen the rendered page or been told exactly where it lives.

When not to use it

Skip this skill for one-off status questions: answer those directly. For price or availability thresholds on a single item, use product-price-monitor. For company news tracking, use competitor-news-monitor. The dashboard is for ongoing, multi-source status that benefits from a persistent page and a scheduled refresh.

Limits and gotchas

The pitfalls the skill calls out are worth reading before you start, because each one costs a scheduled run to discover otherwise.

  • Building the page before verifying the sources. Auth failures then surface on an unattended run.
  • Overwriting last-known-good values with an error page or an empty read.
  • Rendering state into HTML only. dashboard.json is the source of truth; HTML is a projection.
  • Alerting on every refresh instead of on material change.
  • Tracking the wrong grain, such as per-thread when the user thinks per-application.
  • Hardcoding the Hermes home path. Resolve it from the running install, the directory holding config.yaml, and write absolute paths into cron prompts.
  • Calling desktop_preview outside a desktop session. It is only in the toolset for GUI sessions; fall back to the path.

A quick verification pass after setup catches most of these: every field names its source and each source passed one foreground read before scheduling; dashboard.json and index.html exist and agree with every value carrying a retrieval timestamp; failed reads marked fields stale without destroying last-known-good state; ticks delivered only on material change and no-change runs were [SILENT]; the change log replays the dashboard's history from the state file alone; and the dashboard was shown in the preview pane on desktop or its path reported elsewhere.

What pairs with it

Several related skills feed or complement a dashboard. product-price-monitor handles single-item price and availability thresholds. competitor-news-monitor covers company news tracking. email-inbox-triage and google-workspace are useful when email or calendar is one of your dashboard's sources. Reach for those when the job is narrower than a full status page, and keep the dashboard for the view that pulls several of them together.

Skills the docs pair this with

More Productivity skills