feat(updater): opt-in SessionStart update notice for Claude Code (off by default) (PR-3)#180
Merged
Merged
Conversation
… by default) (PR-3)
Increment 2 of the self-update feature: a physician who installed once gets a one-line
"update available" nudge — only if they opt in, with no telemetry and no session reads.
- installers/session_update_check.py (new): SessionStart hook. Never reads stdin (no
cwd/transcript/session id), honors MEDSCI_NO_UPDATE_CHECK=1, uses the shared clock-sane
24h cache + a 4s network timeout, stays silent on any error (never blocks a session), and
prints {"systemMessage": ...} only when latest > installed. Installs nothing.
- update.py: resolve_latest_tag() (tag-only check, no OS asset/digest needed -> works on Linux
too); register/unregister_session_hook() MERGE/unmerge a hook into ~/.claude/settings.json
(idempotent, preserves foreign hooks/settings, removes only ours, refuses to clobber an
unparseable file, preserves the file's mode); install_updater_home now also ships the hook.
- install.py: --enable-update-notify / --disable-update-notify (a normal install never enables it).
- CI: test_session_hook.py (38 cases, offline) on Ubuntu + macOS + Windows; package.json +
distribution_files.json (727) include the hook; README/privacy/CHANGELOG document it.
Folds an adversarial review (4 lenses -> per-finding refutation): 4 confirmed, 5 refuted.
The MAJOR fix: the hook matcher now keys on the home-anchored script path, not the bare
filename, so --disable can't delete an unrelated foreign hook and --enable can't be no-op'd
by a coincidental substring (regression-tested). Also: settings.json mode preserved across
the rewrite; resolve_latest_tag draft/prerelease guard tested.
No release cut.
Centaurioun
pushed a commit
to Centaurioun/medsci-skills
that referenced
this pull request
Jun 26, 2026
Cuts v4.7.0 bundling the self-update foundation (PRs Aperivue#177–Aperivue#180): transactional crash-recoverable installer + per-target state, the one-click verified self-updater, release-pipeline supply-chain hardening (provenance + attestation + updater round-trip gate), and the opt-in SessionStart update notice (off by default). Additive and backward-compatible — no skill/CLI/output-path change; 45 skills / 36 reporting guidelines / 30 detectors unchanged. Version synced across CITATION.cff == package.json == metadata/distribution_manifest.json (4.7.0); CHANGELOG [Unreleased] consolidated to [4.7.0] - 2026-06-22; README "What's New" updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR-3 — opt-in update notice for Claude Code (off by default)
"Increment 2" of the self-update feature (after #177 installer, #178 updater, #179 release
hardening). A physician who installed once gets a one-line "update available" nudge at session
start — only if they opt in, with no telemetry and no session reads. No release is cut.
Why
The updater (#178) exists, but a non-GitHub user has to remember to run it. This adds an opt-in,
privacy-preserving reminder so they actually learn a new version exists — without nagging, tracking,
or auto-installing.
What this adds
installers/session_update_check.py(new) — a Claude Code SessionStart hook that prints{"systemMessage": …}only whenlatest > installed. By construction it:with a 4s timeout, and silent on any error (never delays/blocks a session);
MEDSCI_NO_UPDATE_CHECK=1; installs nothing — it only notifies.update.py—resolve_latest_tag()(tag-only check; needs no OS asset/digest, so it works onLinux too);
register_session_hook/unregister_session_hookMERGE/unmerge the hook into~/.claude/settings.json(idempotent, preserves foreign hooks/settings, removes only ours, refusesto clobber an unparseable file, preserves file mode);
install_updater_homenow also ships the hook.install.py—--enable-update-notify/--disable-update-notify. A normal install neverenables it.
installers/tests/test_session_hook.py(38 offline cases) on Ubuntu +macOS + Windows;
package.json+distribution_files.json(727) include the hook; README"Updating",
docs/update_privacy.md, and CHANGELOG document it.Review
Adversarial review (4 lenses → per-finding refutation, 13 agents): 4 confirmed, 5 refuted. The
MAJOR fix: the hook matcher now keys on the home-anchored script path, not the bare filename,
so
--disablecan't delete an unrelated foreign SessionStart hook and--enablecan't be silentlyno-op'd by a coincidental substring (both regression-tested). Also fixed:
settings.jsonmodepreserved across the atomic rewrite;
resolve_latest_tagdraft/prerelease guard tested.CI
validate(Ubuntu) +foundation-os(macOS + Windows) both runtest_session_hook.py.Draft until CI is green.