All plugins

hermes-newswire

Breaking-news ticker for Hermes Desktop: a scrolling RSS/Atom/JSON-Feed strip above the statusbar with per-source favicons, feed search + discovery, grouping modes, offline cache, and in-app reading. Zero API keys, zero model tokens.

tony-simons-aiowa47DesktopUpdated 1 month ago

About

Breaking-news ticker for Hermes Desktop: a scrolling RSS/Atom/JSON-Feed strip above the statusbar with per-source favicons, feed search + discovery, grouping modes, offline cache, and in-app reading. Zero API keys, zero model tokens.

Hermes Newswire

Hermes Newswire


Support the Project

License: MIT
Tests
Zero API keys
No LLM tokens

A breaking-news ticker plugin for Hermes Desktop — a thin, continuously scrolling newswire strip docked just above the statusbar, backed by a model-free RSS/Atom/JSON-Feed engine.

NEWSWIRE ◆ Hacker News: Why is Google still serving dodgy ads? · 56m ◆ The Verge: Apple is reportedly working on… · 14m ◆ …

What it is

  • Bottom ticker strip — a 28–40px pane docked to the workspace's bottom edge (above the statusbar, never covering it). Continuous marquee, hover-pause, clickable headlines that open in your default browser, source + relative age per story, reduced-motion fallback (static rotating headline), keyboard accessible.
  • Newswire page (/newswire, sidebar row, ⌘K commands) — Latest list with search/filter/unread/mark-read, Sources management with feed discovery (paste https://www.theverge.com, get its feed), Settings.
  • Zero LLM usage — feed retrieval, parsing, dedup, storage, and rendering consume no model tokens and need no API keys.
  • Offline-friendly — SQLite cache keeps the ticker alive when the network is down; refresh resumes silently on reconnect.

Install (unified plugin)

git clone https://github.com/tony-simons-aiowa/hermes-newswire ~/.hermes/plugins/hermes-newswire/
# enable the backend (plugins.enabled must be a real YAML list):
#   edit ~/.hermes/config.yaml → plugins: enabled: [- hermes-newswire]
# restart the desktop's serve child (or restart Hermes Desktop) so the
# backend mounts; the renderer half is lifted automatically:
#   ~/.hermes/desktop-plugins/hermes-newswire/plugin.js

Verify: Mounted plugin API routes: /api/plugins/hermes-newswire/ in ~/.hermes/logs/agent.log.

Install & security scan (FAQ)

hermes plugins install runs a security scan. This plugin installs with a
caution verdict: the scan deliberately inspects test files (hostile
fixtures prove the SSRF gate rejects file:// and loopback URLs — see
tests/test_engine.py, tests/test_http.py) and README install commands
(git clone, ~/.hermes/config.yaml). None of it is runtime behavior.

  • CLI: the installer prints the findings and asks Install anyway? [y/N] — answer y (or run hermes plugins install <repo> --force).
    dangerous verdicts are never installable; caution is a confirm gate.
  • Desktop/dashboard Plugins page: the GUI has no review prompt —
    the install endpoint accepts no decision callback, so a caution verdict
    is refused outright with the full findings list. Use the CLI for the
    interactive confirm (upstream gap; see TROUBLESHOOTING).

Troubleshooting

"Settings does nothing" / "clicking a starter feed does nothing"
The page needs the plugin backend. Checks, in order:

  1. Is the plugin in plugins.enabled in ~/.hermes/config.yaml?
  2. Did the serve child restart after install? (hermes gateway restart,
    or restart Hermes Desktop). The ticker can render from cache while the
    management API 404s.
  3. Open Settings or Sources: a red banner now names the exact failure and
    the fix. Starter-feed clicks surface the backend's error inline
    (e.g. VentureBeat AI could not be added: HTTP 429 fetching … — some
    publishers bot-block the first fetch; try again or use Discover).

Installing reports Security scan blocked plugin install — see the
install FAQ above; confirm through the CLI prompt.

Layout

dashboard/          backend  (FastAPI router → /api/plugins/hermes-newswire/)
  manifest.json     name/label/version/api pointer
  plugin_api.py     feed engine, SQLite store, refresh loop, routes
desktop/            renderer (plain ESM plugin.js, loaded uncompiled)
tests/              pytest suite (fixtures only — no live sites)

Supported formats & discovery

RSS 2.0, RSS 1.0/RDF, Atom, JSON Feed. Discovery: <link rel="alternate"> tags first, then well-known paths (/feed, /rss.xml, /atom.xml, …). Direct feed URLs skip discovery.

Security

Source URLs are untrusted: http/https only (no file/ftp), loopback/private/link-local/CGNAT/metadata addresses blocked (literal, hex/octal legacy forms, AND post-DNS resolution), redirects validated per hop (max 3), 5s connect / 15s total timeouts, 5 MB body cap, all feed HTML stripped before storage. OPML import validates every URL through the same gates. No telemetry, no remote service, no secrets.

Favicons are proxied (GET /icon.json?url=…): the backend fetches icons
through the same SSRF gate + validated-IP pinning as feeds and returns a
base64 data URL (image content-type allowlist, 64 KB cap, 24 h TTL cache,
failures return data_url: null plus an error reason — never raw bytes).
The renderer's <img> tags therefore never resolve attacker-controlled
hostnames directly; the desktop SDK exposes no raw-byte door a plugin could
use to fetch binaries itself (upstream seam gap worth closing generically).

Settings

Ticker enabled · scroll speed · text size 9–20px (strip height follows) · pause on hover · show source · relative time · only-unread · max article age · max headlines · refresh interval (30s–24h, default 5min). Conditional GETs (ETag/Last-Modified → 304) keep polling cheap.

Test & verify

env -u PYTHONPATH ~/.hermes/hermes-agent/venv/bin/python -m pytest tests/ -q
node --check desktop/plugin.js
node tests/ui/esm-render.mjs        # stateless render smoke (26 checks)
node tests/ui/interaction.mjs       # stateful interaction tests (29 checks)

Agent-friendly development

Coding agents (Hermes, Codex, Claude Code, Cursor, …) start with the root
AGENTS.md — architecture map, critical invariants, exact
verification commands, and a definition of done. The deep reference is
docs/AGENT_GUIDE.md (data flow, security model,
safe-change recipes).

Quick gates before any PR: env -u PYTHONPATH <hermes-venv>/bin/python -m pytest tests/ -q ·
node --check desktop/plugin.js · hermes plugins validate . --json.

Status

v0.1.0 — feature-complete (backend, page, ticker, hardening, search, favicons, grouping) with an independent QA-gated history. 119-test suite + ESM render smoke. Built as a standalone unified plugin against the Hermes Desktop plugin SDK (catalog submission pending).

README from the reviewed commit e6b438e; it updates when the author re-pins.

More by tony-simons-aiowa

3 plugins by tony-simons-aiowa in the catalog.

tony-simons-aiowaagent-hold-emNo-Limit Texas Hold 'Em for Hermes Desktop: play with three isolated Hermes profile agents using play chips only. Agent decisions use configured models and may consume provider tokens; this is a local game, not gambling software. Disclosure — each opponent is a zero-tool Hermes agent run in-process under the local Hermes profile you select for it, using that profile's configured provider credentials and spending its tokens; reads every local profile's name, model and avatar for the picker; stores the table (including hole cards) in plugin-data/agent-hold-em/table.json.CommunityDesktop app1tony-simons-aiowahermes-fleet-connectorOwner-approved universal phone pairing and bundled read-only Live Operations reporting for selected Hermes profiles. Disclosure — paired phones get broad fleet:operator access over the internet, including cron jobs (unattended runs), Kanban task dispatch and media reads, and see live session titles/previews and subagent goals from the profiles you select for reporting; any messaging account you make an owner (with a one-time claim code from `hermes fleet claim`) can create pairing links and approve phones from a private chat, so that account's security is your host's security. Runs an explicitly activated background connector/reverse proxy behind your HTTPS origin and may launch a local Hermes backend; legacy QR flow opens a private local browser. Keeps an owner-only control socket in the system temp directory, plus pairing/owner state and shared local snapshots; reads selected profiles' session registries through private read-only imports. `hermes fleet reporting configure --apply` edits the selected profiles' config.yaml (with a backup). Local idle/retirement maintenance is explicit and not exposed to phones. Reporting adds no control power.Communityplatform