Skip to content

feat(web): one notification feed of every daemon's notices - #374

Closed
futrime wants to merge 1 commit into
mainfrom
feat/web-notifications
Closed

futrime wants to merge 1 commit into
mainfrom
feat/web-notifications

Conversation

@futrime

@futrime futrime commented Oct 12, 2026

Copy link
Copy Markdown
Member

Unit 5 of the multi-daemon + notifications plan: contract C7 on the local server.

What

  • New src/hmz/web/notifications.py:
    • GET /api/notifications returns {items, unread}, newest first. Each item is a C4 notice plus its own id, daemon (local or the entry name) and read. The last 200 are kept in memory.
    • GET /api/notifications/stream sends SSE notification events and resumes by Last-Event-ID or ?last=. A page whose last id came from an earlier server starts over.
    • POST /api/notifications/read takes {ids} or {all: true}. POST /api/notifications/clear empties the feed.
    • GET and POST /api/notifications/settings read and write C2 under notifications in settings.yaml, through coganchor.settings.read and .changes. All kinds default to true. Anything else gets a 400 and nothing is written.
  • Sources:
    • Local site.notices (C4 .heard).
    • Each SSH daemon named in settings.yaml daemons (C1) whose site.remotes.state(name) is up. It is followed through reached(name): sign in with /?key= the way a browser does, which yields the remote's own hmz-<port> cookie. Then read /api/notices for last, then follow /api/notices/stream.
    • Both sources are looked up with getattr every 2 s, so this is green on its own and picks up the sibling units once they land.
  • Kinds are filtered by C2 before an item is stored. Preferences are re-read for each notice, so a change applies at once.
  • Docs: docs/reference/web.md (Notifications API) and docs/reference/settings.md (notifications key).

Tests

  • tests/unit/web/test_notifications.py: public names, with fake notices.
  • tests/integration/test_web_notifications.py: the served site with a fake site.notices, a fake site.remotes, and a stand-in remote interface on a local port. Covers the cross-daemon feed, filtering, settings written to settings.yaml, refusals, read, clear, and the SSE stream with resume.
  • Live: hmz web --port 0, then curl every endpoint and check settings.yaml.

🤖 Generated with Claude Code

Serve /api/notifications, its stream, read, clear and settings on the
local interface. Notices are heard from site.notices and followed off each
reached SSH daemon's /api/notices/stream, tagged with the daemon, filtered
by the notifications kinds in settings.yaml, and the last 200 kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 12, 2026 14:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@futrime

futrime commented Oct 12, 2026

Copy link
Copy Markdown
Member Author

Landed together in #385.

@futrime futrime closed this Oct 12, 2026
@futrime
futrime deleted the feat/web-notifications branch October 12, 2026 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants