toga-ai 1.0.587 → 1.0.588
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -123,7 +123,8 @@ poll's:
|
|
|
123
123
|
- The **first successful poll is the baseline**, so opening the page mid-outage is **silent**
|
|
124
124
|
(the standing tint, being level-triggered, still shows immediately).
|
|
125
125
|
- A state that simply persists never re-alarms.
|
|
126
|
-
- A full recovery to operational is **silent** (
|
|
126
|
+
- A full recovery to operational is **visually silent** (no popup, no tint) but now plays a
|
|
127
|
+
distinct **recovery chime** — see the recovery event below.
|
|
127
128
|
- It fires on **any change of non-operational state** — `r.role !== previous.get(r.key)`, where
|
|
128
129
|
the row set only ever holds non-operational monitors, so good→degraded, good→offline,
|
|
129
130
|
degraded→offline **and offline→degraded** all alert. An earlier version compared severity
|
|
@@ -134,11 +135,30 @@ poll's:
|
|
|
134
135
|
The event presentation, held for `ALERT_HOLD_MS` (5s):
|
|
135
136
|
|
|
136
137
|
- **Sound** — Web Audio beeps, synthesised at runtime, so there is **no audio asset to ship**.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
Each role's sound is defined in a single `ALERT_SOUND` table keyed by role, read by a
|
|
139
|
+
generalised `playBeeps(role)` (signature unchanged: role → bool). Each entry carries a beep
|
|
140
|
+
**count**, base **freq** (Hz), a per-beep **step** (Hz added to each successive beep — `0` =
|
|
141
|
+
flat, positive = a rising chime), duration/gap/volume, and a **wave** shape. Current tuned
|
|
142
|
+
values: **warning (degraded) = 3× square @ 720 Hz** (flat), **critical (offline) = 4× square
|
|
143
|
+
@ 410 Hz** (flat), **recovered = 3× square rising chime 620 → 800 → 980 Hz** (freq 620,
|
|
144
|
+
step 180). Distinct count, pitch and the rising vs. flat contour make each event
|
|
145
|
+
recognisable across a room without looking. The three sounds were tuned by ear in a
|
|
146
|
+
throwaway standalone "Monitor Sound Lab" browser page and the final numbers ported in — the
|
|
147
|
+
lab is not part of the repo.
|
|
148
|
+
- **Popup** — a centre overlay naming each affected monitor. **Bad-state events only** —
|
|
149
|
+
recovery fires no popup.
|
|
141
150
|
- **Blink** — the tint element gains `.is-blinking` for the 5s pulse, then the colour **holds**.
|
|
151
|
+
**Bad-state events only** — recovery fires no blink and no tint.
|
|
152
|
+
|
|
153
|
+
**Recovery event — audio-only, by design.** `useMonitorAlerts` also computes `recovered` = keys
|
|
154
|
+
that were non-operational in the previous poll and have **dropped out of `model.rows`** this poll,
|
|
155
|
+
and calls `playBeeps('recovered')` (the rising chime) for them. It deliberately fires **no popup
|
|
156
|
+
and no screen tint**: the level-triggered standing tint already clears itself when a row leaves
|
|
157
|
+
the set, and a green "all clear" popup/flash would fight the "the board only shouts when something
|
|
158
|
+
is wrong" design. So recovery is silent **visually** but audible. Two edge rules: the **first
|
|
159
|
+
poll is still the baseline** (opening the page mid-outage does not chime), and if a bad-state
|
|
160
|
+
change and a recovery land in the **same 5s poll the bad-state alert wins** that tick, avoiding
|
|
161
|
+
overlapping sounds (simultaneous transitions are rare).
|
|
142
162
|
|
|
143
163
|
**State — `standingRole(model)`** returns `critical` if any row is offline, else `warning` if any
|
|
144
164
|
is degraded, else `null` (no tint). The tint element only renders while `standingRole` is
|
|
@@ -148,8 +168,10 @@ Note the two can legitimately show different colours at once: the tint always re
|
|
|
148
168
|
**worst-current** state while the popup reflects **the event**, so a degraded-event popup can sit
|
|
149
169
|
on a red screen because something else is still offline. That is correct, not a bug.
|
|
150
170
|
|
|
151
|
-
Verified across full cycles
|
|
152
|
-
|
|
171
|
+
Verified across full cycles (against the original 1-beep-720 / 2-beep-990 tuning; the current
|
|
172
|
+
values are 3×720 / 4×410 / recovered 620→800→980): distinct sounds per event, silent on
|
|
173
|
+
unchanged, recovery now chimes but stays visually silent, popup held 4982 ms and 4955 ms against
|
|
174
|
+
the 5s spec; amber standing → red when offline
|
|
153
175
|
joined (priority) → amber when offline cleared → no tint on full recovery, with the blink
|
|
154
176
|
stopping after 5s and the colour held. Circle verified against the DOM: `#0ca30c` all-clear,
|
|
155
177
|
`#fab219` degraded only, `#d03b3b` with 1 degraded + 1 offline, and `textNodesInSvg = 0`.
|
|
@@ -209,8 +231,9 @@ reduced-motion viewer never lands on a fully-invisible (opacity 0) glow.
|
|
|
209
231
|
OneUptime call returns HTTP 200 with a malformed or empty body, `buildMonitorModel` yields
|
|
210
232
|
total 0, empty buckets and empty rows. The status pill correctly degrades to "Unknown", but
|
|
211
233
|
the affected-list card still reads **"All 0 monitors are operational"**, and any
|
|
212
|
-
previously-degraded monitor silently disappears
|
|
213
|
-
|
|
234
|
+
previously-degraded monitor silently disappears — and, worse now that recovery is audible,
|
|
235
|
+
the mass drop-out is **indistinguishable from a full recovery**, so the panel plays the happy
|
|
236
|
+
**recovery chime** for every vanished monitor on a parse failure. Since the standing
|
|
214
237
|
tint and the status circle are both driven by that same empty row set, a parse failure also
|
|
215
238
|
**clears a standing red screen back to green** — the most reassuring possible display of a
|
|
216
239
|
total loss of visibility. Recommended fix: treat "zero resources parsed" as an **error
|
|
@@ -231,6 +254,18 @@ summary, and caches ~5s. Rationale:
|
|
|
231
254
|
alerting really wants (today the baseline resets every time a tab reloads).
|
|
232
255
|
|
|
233
256
|
## Change history
|
|
257
|
+
- 2026-08-14 — Generalised alert-sound synthesis and added a **recovery chime**. The old
|
|
258
|
+
`BEEP_COUNT`/`BEEP_HZ`/`BEEP_MS`/`BEEP_GAP_MS`/`BEEP_VOLUME` constants and the square-wave-only
|
|
259
|
+
`playBeeps` were replaced by a single per-role `ALERT_SOUND` table (count / freq / per-beep
|
|
260
|
+
`step` / duration / gap / volume / `wave`) read by a generalised `playBeeps(role)` (signature
|
|
261
|
+
unchanged). Retuned to degraded 3×square@720, offline 4×square@410 (was degraded 1×@720,
|
|
262
|
+
offline 2×@990). Recovery — a monitor dropping out of the non-operational row set — now plays
|
|
263
|
+
a distinct rising chime (620→800→980, freq 620/step 180) and is **audio-only by design**: no
|
|
264
|
+
popup, no tint (the standing tint already self-clears; a green "all clear" flash would fight
|
|
265
|
+
the "only shouts when wrong" design). First poll stays the silent baseline; a bad-state change
|
|
266
|
+
and a recovery in the same tick let the bad-state alert win. Sounds were tuned by ear in a
|
|
267
|
+
throwaway standalone browser "Sound Lab" (not a repo file) and ported in. Corrects the prior
|
|
268
|
+
"recovery is silent" and old beep-count/pitch documentation. (jcardinal)
|
|
234
269
|
- 2026-08-14 — The standing (level-triggered) edge tint now **slowly breathes** its opacity
|
|
235
270
|
0→1→0 on a 7s ease-in-out loop (`@keyframes alert-breathe`) instead of holding a static tint,
|
|
236
271
|
so a still-broken screen draws a distant eye. The fast 0.7s `.is-blinking` event pulse still
|
package/package.json
CHANGED