Repository navigation
v3.8.1 — daemon picks up new code after PyPI upgrade
Fixes a long-standing daemon staleness bug: after pip install -U claude-statusbar, the long-lived daemon kept serving old renders until manual cs daemon stop && cs daemon start.
Why it happened
The fast-mode daemon process is launched once (via cs --setup --fast or launchd) and reuses its in-memory imports for as long as it lives. After a PyPI upgrade:
- The thin client
cs renderreads~/.cache/claude-statusbar/sessions/<sid>/rendered.meta.json, seesgenerated_atis fresh (< 5 s), and serves the daemon's pre-rendered output — which is generated by old code. _spawn_daemon_asyncrefuses to start a new daemon because the old one's pidfile is still valid.- Result: users had to manually restart the daemon to see any updates after a PyPI upgrade.
How v3.8.1 fixes it
- Daemon records
daemon_started_at = time.time()when it boots and writes that intorendered.meta.jsonevery tick. - Thin client computes
max(*.py mtime)of the installedclaude_statusbar/package directory via a singleos.scandir. - New gate in
_is_fresh(): ifpkg_mtime > daemon_started_at, the daemon is older than the code on disk → treat meta as stale. - When stale due to code drift, thin client
SIGTERMs the daemon pid recorded in the meta. The existing inline-fallback +_spawn_daemon_asyncpath brings up a fresh daemon on the next render tick. - Pre-3.8.1 daemons don't write
daemon_started_at; the new gate skips them so the v3.8.0 → v3.8.1 rollout is smooth (the daemon restart after the upgrade is what activates the new behavior).
Performance
os.scandirover the ~30.pyfiles in the package: ~50–100 μs per render tick. Negligible against the < 5 ms thin-client budget.- No new top-level imports —
signalis lazy-imported inside_signal_outdated_daemonsotest_import_perfinvariants stay green.
Stats
394 → 399 tests (5 new in tests/test_daemon_freshness.py). All passing.
Upgrading
- New installs: nothing to do.
- Existing fast-mode users on v3.8.0: PyPI auto-updater will pull v3.8.1 within a day. The first
cs renderafter the upgrade kills the old daemon and respawns. Worst case 1 s of inline rendering during the transition.