fix(usage): address code-review findings in plan-usage telemetry

Review of the plan-usage chip feature (commits since 1.0.0) surfaced several
issues; this fixes all confirmed findings:

- HIGH: applyStatusLineConfig clobbered a user's hand-authored statusLine on
  the enable path (the isOurs guard only protected disable). Now bails out when
  an existing statusLine isn't ours, on both the enable and disable paths.
- MED: StatusTelemetrySchema used z.optional() (rejects null) on Claude's
  undocumented statusline fields — a single stray null 400'd the entire POST and
  silently killed the chip's data feed. Switched the modeled fields to .nullish().
- MED: dropping the Token Count / Show Cost header toggles left their features
  reading settings.showTokenCount/showCost, but saveAppSettings rebuilds settings
  fresh from the DOM, dropping those keys and resetting them to defaults on every
  save (re-enabling the token chip with no UI to turn it off). Preserve the prior
  stored preference.
- telemetrySignature keyed on contextUsedPercentage (never displayed) and the raw
  unrounded %, churning a redundant SSE broadcast + localStorage write + identical
  chip re-render on every assistant message. Now keys on the rounded displayed
  window values only.
- Plan-usage chip flashed hidden on load (no server-side reveal): renderIndexHtml
  now strips header-plan-usage--hidden when enabled, matching btn-multimonitor;
  fixes the FOUC and makes the "server renders initial state" comments accurate.
- Serialize all settings.local.json read-modify-write writers in hooks-config via
  a shared per-path mutex (previously lock-free; concurrent session-create +
  settings-toggle on the same repo could lose writes).
- Hardened the chip's innerHTML against any future string field; removed the dead
  _latestPlanUsage field; clamped ctx% in the footer formatter; corrected the
  session-create comment (the path is add-only by design — a per-repo settings
  file is shared by sibling sessions).
- Tests: new test/routes/status-telemetry-routes.test.ts (route behavior, dedup,
  null-tolerance) + NaN/Infinity/fractional and signature-churn unit tests; made
  server-index-title.test.ts deterministic against the ambient settings.json.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arkon
2026-06-14 07:33:52 +02:00
co-authored by Claude Opus 4.8
parent f69cd4874c
commit 534712e50f
10 changed files with 352 additions and 118 deletions
+8
View File
@@ -1124,6 +1124,14 @@ export class WebServer extends EventEmitter {
if (settings.showMultiMonitorButton === true) {
html = html.replace(' btn-multimonitor--hidden', '');
}
// Plan-usage chip: same pattern. Ships with `header-plan-usage--hidden` (App
// Settings → Display → "Plan Usage Limits", default off); strip it server-side
// when enabled so the chip doesn't flash hidden on every reload before the
// client's applyHeaderVisibilitySettings runs. showPlanUsageLimits is a synced
// (non-display) setting, so readSettings sees the persisted value here.
if (settings.showPlanUsageLimits === true) {
html = html.replace(' header-plan-usage--hidden', '');
}
// Detached single-session ("solo") window: inject the target session id so
// the client can enter solo mode even if a (network-first) service worker
// later serves a cached shell. The client primarily detects solo mode from