Skip to content

v3.3.0 - Push notifications + Markdown viewer

Choose a tag to compare

@theyashgupta theyashgupta released this 31 Aug 08:40
· 34 commits to main since this release
5ba5b97

v3.3.0 - Push notifications + Markdown viewer

An agent hits a question it cannot answer alone, and the session stops. The board knows. You, three rooms away with the laptop closed, do not. Dispatch now tells your devices. When a session flips to needs-input, every phone and laptop you subscribed gets a push, with the tab closed, and one tap lands you on the exact card that is waiting.

See it

Dispatch v3.3.0 push notifications and the markdown viewer

Higher-quality video: dispatch-v3.3.0-push-viewer.mp4

A push when a session needs you

You enable push from Settings, Notifications. The browser permission prompt fires only on that click, never on page load. Subscribe as many devices as you want, and every one of them is alerted. On iOS, install Dispatch to the Home Screen first, and Settings walks you through it.

Only needs-input sends a push. A finished agent does not buzz your phone. When the same card asks again, the new notification replaces the old one and still alerts, so a chatty session cannot stack up a shade full of stale alerts. If you have a tab open, the push and the in-tab notification collapse into one. Tapping a notification focuses an open Dispatch tab and opens the card, or opens a new tab cold on that card. Push also works over the remote tunnel, behind the same auth gate as everything else, and each device's notification links back through the origin it subscribed from.

Dead subscriptions clean themselves up. When a push service answers 404 or 410, the row is pruned on the spot.

The crypto is ours, and reality graded it

The Web Push payload encryption (RFC 8291) and the VAPID signature (RFC 8292) are hand-rolled on node:crypto, keeping the runtime dependency count at zero for the whole push track. The proof does not come from this repo agreeing with itself. The test harness subscribes a real headless Chrome to the real push service, drives a real needs-input transition, and the push service accepted the message (HTTP 201). Strip one parameter from the signature and the same service rejects it (403). A real phone over a real tunnel, with the tab fully closed, received the notification and landed on the right card.

The service worker that makes this possible has no fetch handler, on purpose. It cannot intercept a single app request, so it can never break loading or updates, and it is served no-cache so a new version is never stuck behind an old one.

Markdown, rendered where you click it

Agents write markdown constantly: plans, summaries, reports. The terminal links them, and until now those links went nowhere useful. Cmd-click a .md link in a session terminal and it opens rendered in a new tab, on a Dispatch route, never a raw file:// page.

The view is read-only and safe by construction. Raw HTML in the file never reaches the DOM, and images render as links, the same posture the board's markdown already uses. Fenced code blocks get syntax highlighting. Long files get a table-of-contents sidebar, headings get anchors, and relative links between .md files navigate inside the viewer with a working back button.

The backend route behind it serves only .md files inside your registered workspaces. Path traversal, symlink escapes, and sibling-prefix tricks were each tried for real against a live server, and each one gets the same flat 404.

Limits, stated plainly

iOS delivery requires the Home-Screen-installed app, which is Apple's constraint, not ours. After the tunnel hostname rotates, an already-delivered notification still deep-links to the old hostname, because pruning acts only on 404 and 410, by design. The viewer's table of contents hides below 1024px wide, a deliberate cut rather than a drawer.


Full changelog: v3.2.0...v3.3.0

Requires Node ≥ 22.22, tmux, ttyd, git, and the Claude Code CLI. Setup is in the README.