Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,8 @@ Alert rows of the table above from the `--droplet-*` roles in `src/styles.css`.
not restore, `--term-bg` and the rule. A tab strip takes the same surface as the header over
it from `769px` (`--strip-bg`: `--bg` under the chat lens, `--term-bg` otherwise, `--bg-panel`
below `769px`) and keeps its hairline, under the chat the one line over the transcript (no
fade under it). The update notice and a PC's action banner are drawn in the pane column, over
the tab strip, never across the window: the sidebar and its top row stay one piece. A layout
fade under it). The update notice, the alerts health notice and a PC's action banner are drawn in
the pane column, over the tab strip, never across the window: the sidebar and its top row stay one piece. A layout
call the palette made that a PC's bridge from before the route answered 404 to reads there too,
for a moment, as a `.pane-notice` line of `--status-blocked` `--fs-xs` text under a hairline
("This PC's bridge does not offer this yet"); the tab's menu says the same at the strip's end. With the
Expand Down Expand Up @@ -3027,6 +3027,32 @@ Alert rows of the table above from the `--droplet-*` roles in `src/styles.css`.
- Not for the pane already open, and not while the app is hidden (system notifications cover that).
- Reduced motion: it fades in and out where it rests, without falling or spreading.

### Alerts health notice (`.update-notice.is-alerts`)
- This device asked for alerts and the last push to it failed for good: one line in the pane
column, on the update notice's row (`.update-notice`: `--space-2 --space-4` padding, `--fs-xs`,
a hairline under it), tinted `--status-blocked-tint` with `--text-strong` text and a `BellOff`
glyph in `--status-blocked` before the sentence, so the state is not carried by the tint alone.
One sentence, one `.btn` at the end of the line (under it on a phone): **Turn alerts on again**
where subscribing anew mends it (the push service retired the subscription, the server does not
know it, it was made for another server key), reading **Turning alerts on…** and disabled
while the repair runs; **Alerts**, opening Settings → Alerts, for a refusal, which
re-subscribing does not mend and Send test answers. Not dismissible: the line leaves on the
push the repair or a test proves, or when alerts are turned off here.
- What it says is decided once (`lib/pushHealth.ts`) and read by this line and by the Test
notification row of Settings → Alerts alike, so the two never disagree and no second banner
competes: Settings' hint carries the same sentence, its **Turn alerts on again** is the same
repair, and either place's button waits while the other's runs. A fault is a permanent failure
strictly newer than the last success; a failure an alert has since gone past, no answer,
throttling and a server error are history, at most one dim line in Settings. A denied
permission has no notice (the More menu's Alerts item already reads **On in the app**);
Settings says what to allow. The PC out of reach changes nothing, and nothing is said of a
subscription nobody has looked at: no probe push is ever sent to find out.
- Design: herdr's own single-notice flow (the update, exposure and PC-action rows) and the
existing Send test / Turn alerts on again pair, extended rather than a second surface. Neither
the Codex app nor the Claude app surfaces push-delivery health, so there is no precedent to
follow there; Agent of Empires' classifier (MIT, THIRD_PARTY_NOTICES.md) is adapted for the
rule, with its repair narrowed to the faults re-subscribing mends.

### Token gate
- A centered password card replaces the entire shell while authentication is required. It has a real
label, autofocused field, primary Unlock button and linked alert text.
Expand Down
3 changes: 2 additions & 1 deletion THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ The sidebar's label filter (`src/lib/sidebarFilter.ts`) adapts the idea of
`web/src/components/sidebar/filterGroups.ts` at revision
`b3141c8a310338dedf87ebbd13a0d67ecd69030d`, that a sidebar row survives a typed filter when it, a
header over it or a row under it matches; its substring matcher, facets and sunk/trash semantics are
not taken over. Under the MIT License printed above, with this copyright notice:
not taken over. `src/lib/pushHealth.ts` adapts its push health classifier (`web/src/lib/pushHealth.ts`)
at the same revision. Under the MIT License printed above, with this copyright notice:

```
Copyright (c) 2026 Nathan Brake
Expand Down
9 changes: 9 additions & 0 deletions changelog.d/device-push-health.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
### Added
- A device whose push alerts stopped is told why: when the push service retired its subscription,
the server no longer knows it or it was made for another server key, one line over the pane and
the Test notification row of Settings → Alerts say so and offer Turn alerts on again, which
subscribes the device anew; a refusal is told and opens Alerts, where Send test answers it. The
server keeps the outcome of the last push to each subscription (`push-delivery.json`, owner-only,
bounded like the retired list) and answers `POST /api/push/status` to the subscription's owner
holding its keys alone. A failure older than the last success, no answer, throttling or a server
error never raises the line, and no probe push is sent to find out.
1 change: 1 addition & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ bun scripts/key-bar-hold-repeat-regression.ts # phone touch key-bar taps, holds
bun scripts/settings-pages-demo-regression.ts # every Settings page on a 390px and a 320px phone, and Back stepping out of the dialog
bun scripts/interface-font-demo-regression.ts # Interface font at 390 and 1440: System and a typed list lead --font-ui, a reload keeps it, Default restores it; the message box takes the Chat font
bun scripts/theme-first-paint-demo-regression.ts # the saved theme in every painted frame before and after the app starts, root and demo builds under the app's CSP
bun scripts/push-health-demo-regression.ts # the alerts health notice with a stand-in PushManager: a retired subscription told once over the pane and in Settings, repaired once; a refusal, a key mismatch, denied, unsupported, offline, loading and a watching device's refused test, at 390 and 1440, light and dark, Korean at 390
bun scripts/chat-browser-qa.ts # chat lens end to end
bun scripts/omo-plan-browser-regression.ts # OmO todo progress and plan panel on isolated native fixtures
bun scripts/pane-input-focus-demo-regression.ts # the input focus shortcut against fictional panes
Expand Down
1 change: 1 addition & 0 deletions scripts/ci-browser.sh
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ run_script scripts/settings-pages-demo-regression.ts
run_script scripts/interface-font-demo-regression.ts
run_script scripts/theme-first-paint-demo-regression.ts
run_script scripts/security-summary-demo-regression.ts
run_script scripts/push-health-demo-regression.ts
run_script scripts/cliproxy-settings-regression.ts
run_script scripts/pane-input-focus-demo-regression.ts
run_script scripts/terminal-keyboard-demo-regression.ts
Expand Down
Loading
Loading