diff --git a/optional-skills/productivity/live-dashboard/SKILL.md b/optional-skills/productivity/live-dashboard/SKILL.md index dad5dfc8d0..c117965793 100644 --- a/optional-skills/productivity/live-dashboard/SKILL.md +++ b/optional-skills/productivity/live-dashboard/SKILL.md @@ -2,12 +2,13 @@ name: live-dashboard description: "Build self-updating dashboards from live sources." version: 0.2.0 -author: Hermes Agent +author: Teknium (teknium1), Hermes Agent license: MIT platforms: [linux, macos, windows] metadata: hermes: - tags: [Dashboards, Monitoring, Status, Automation, Reporting] + tags: [dashboards, monitoring, status, automation, reporting] + category: productivity related_skills: [product-price-monitor, competitor-news-monitor, email-inbox-triage, google-workspace] blueprint: schedule: "0 8 * * *" @@ -16,7 +17,7 @@ metadata: # Live Dashboard -Turn one sentence — "make a dashboard for our visa applications, update it daily from the email threads and the case-status site" — into a persistent, self-refreshing status page. The user describes what they want to see; you define the data contract, build a self-contained HTML dashboard, verify one live refresh, then schedule the recurring tick. Inspired by Energy's (getenergy.com) natural-language live dashboards, adapted to Hermes's cron + connector architecture. +Turn one sentence — "make a dashboard for our visa applications, update it daily from the email threads and the case-status site" — into a persistent, self-refreshing status page. The user describes what they want to see; you define the data contract, build a self-contained HTML dashboard, verify one live refresh, then schedule the recurring tick. Setup runs once in the foreground; the recurring refresh runs as a `cronjob` tick. Installing this skill offers a daily all-dashboards sweep via `/suggestions` (the frontmatter blueprint). diff --git a/tests/skills/test_live_dashboard_skill.py b/tests/skills/test_live_dashboard_skill.py index 5b7537746d..aa9ede91b9 100644 --- a/tests/skills/test_live_dashboard_skill.py +++ b/tests/skills/test_live_dashboard_skill.py @@ -1,9 +1,4 @@ -"""Tests for the live-dashboard optional skill. - -Inspired by Energy's (getenergy.com) natural-language live dashboards — -describe what you want to see in one sentence, get a persistent -self-refreshing status page fed by email/web/file sources. -""" +"""Tests for the live-dashboard optional skill.""" import re from pathlib import Path @@ -47,44 +42,28 @@ def test_related_skills_resolve_in_repo(): assert hits, f"related_skills entry does not resolve in-repo: {name}" -def test_setup_tick_split(): - """The skill must separate one-time setup from the recurring cron tick.""" - _, body = _frontmatter_and_body() - assert "Setup (foreground, once)" in body - assert "Tick (each scheduled run)" in body - assert "cronjob(action=" in body, "must wire scheduling through the cronjob tool" - - -def test_state_discipline_present(): - """State-file source of truth + stale-read handling must be explicit.""" - _, body = _frontmatter_and_body() - assert "dashboard.json" in body - assert "source of truth" in body - assert "last-known-good" in body or "last good value" in body - assert "never hand-edit HTML state" in body - assert "[SILENT]" in body, "no-change ticks must stay silent" - - -def test_source_verification_before_scheduling(): - _, body = _frontmatter_and_body() - assert "Only after step 3 succeeded" in body - assert "one bounded foreground read" in body - - -def test_steps_have_completion_criteria(): +def test_procedure_is_structured_setup_tick_show(): + """The skill splits into setup / scheduled tick / render phases, each phase is a + numbered-step procedure, and every step states a completion criterion.""" _, body = _frontmatter_and_body() + phases = re.findall(r"^## Procedure — (.+)$", body, re.MULTILINE) + assert len(phases) == 3, phases steps = re.findall(r"^### \d+\..*?(?=^### \d+\.|^## )", body, re.MULTILINE | re.DOTALL) assert len(steps) >= 7 for step in steps: assert "Done when" in step, f"step missing completion criterion: {step[:60]!r}" + for heading in ("## When to Use", "## Prerequisites", "## Pitfalls", "## Verification"): + assert heading in body, heading -def test_desktop_preview_with_path_fallback(): - """Desktop sessions render in the preview pane; everything else gets the file path. - The Hermes home directory is never hardcoded in prose the agent executes.""" +def test_tools_wired_and_home_not_hardcoded(): + """Scheduling goes through `cronjob`, desktop rendering through `desktop_preview`, + no-change ticks stay silent, and the Hermes home path is resolved, never assumed.""" _, body = _frontmatter_and_body() - assert 'desktop_preview(action="open"' in body - assert "report the absolute path" in body + assert re.search(r"cronjob\(action=\"create\"", body) + assert re.search(r"desktop_preview\(action=\"open\"", body) + assert "[SILENT]" in body + assert "dashboard.json" in body assert "~/.hermes" not in body @@ -98,4 +77,4 @@ def test_frontmatter_blueprint_is_a_valid_installed_blueprint(): job = blueprint_to_job_spec(spec) assert job["skills"] == ["live-dashboard"] assert len(job["schedule"].split()) == 5, f"invalid cron expr: {job['schedule']}" - assert "[SILENT]" in job["prompt"] and "~/.hermes" not in job["prompt"] + assert "[SILENT]" in job["prompt"] and "~/.hermes" not in job["prompt"] \ No newline at end of file diff --git a/website/docs/user-guide/skills/optional/productivity/productivity-live-dashboard.md b/website/docs/user-guide/skills/optional/productivity/productivity-live-dashboard.md index 05a91c24a5..978f70e5c5 100644 --- a/website/docs/user-guide/skills/optional/productivity/productivity-live-dashboard.md +++ b/website/docs/user-guide/skills/optional/productivity/productivity-live-dashboard.md @@ -17,10 +17,10 @@ Build self-updating dashboards from live sources. | Source | Optional — install with `hermes skills install official/productivity/live-dashboard` | | Path | `optional-skills/productivity/live-dashboard` | | Version | `0.2.0` | -| Author | Hermes Agent | +| Author | Teknium (teknium1), Hermes Agent | | License | MIT | | Platforms | linux, macos, windows | -| Tags | `Dashboards`, `Monitoring`, `Status`, `Automation`, `Reporting` | +| Tags | `dashboards`, `monitoring`, `status`, `automation`, `reporting` | | Related skills | [`product-price-monitor`](/docs/user-guide/skills/bundled/productivity/productivity-product-price-monitor), [`competitor-news-monitor`](/docs/user-guide/skills/bundled/research/research-competitor-news-monitor), [`email-inbox-triage`](/docs/user-guide/skills/bundled/email/email-email-inbox-triage), [`google-workspace`](/docs/user-guide/skills/bundled/productivity/productivity-google-workspace) | ## Reference: full SKILL.md @@ -31,7 +31,7 @@ The following is the complete skill definition that Hermes loads when this skill # Live Dashboard -Turn one sentence — "make a dashboard for our visa applications, update it daily from the email threads and the case-status site" — into a persistent, self-refreshing status page. The user describes what they want to see; you define the data contract, build a self-contained HTML dashboard, verify one live refresh, then schedule the recurring tick. Inspired by Energy's (getenergy.com) natural-language live dashboards, adapted to Hermes's cron + connector architecture. +Turn one sentence — "make a dashboard for our visa applications, update it daily from the email threads and the case-status site" — into a persistent, self-refreshing status page. The user describes what they want to see; you define the data contract, build a self-contained HTML dashboard, verify one live refresh, then schedule the recurring tick. Setup runs once in the foreground; the recurring refresh runs as a `cronjob` tick. Installing this skill offers a daily all-dashboards sweep via `/suggestions` (the frontmatter blueprint).