fix(skills): scope What's New pill to Installed tab + reword updated→changed

Issue #78 — The "What's New" pill at the top of the Skills page
announced "18 new, 3 updated since you last looked" while the Updates
sub-tab simultaneously said "No Updates / All skills are up to date."
Two surfaces measuring two different things both used the word
"update": the pill counts local file deltas since the user last
clicked "Mark as seen", while the Updates body runs `hermes skills
check` to find skills with newer upstream versions available. From
the user's seat the screen contradicted itself.

Two changes:

1. Render the pill only on the Installed sub-tab (Mac + ScarfGo).
   Local file deltas are contextually meaningful only on the tab
   that surfaces installed skills; showing them above Browse Hub or
   Updates was misleading.

2. Reword the pill: "X updated since you last looked" → "X changed
   since you last looked". Keeps `SkillSnapshotDiff.updatedCount` as
   the field name (it's still about file changes, not version bumps);
   only the user-visible string changes. Removes the vocabulary
   collision with the Updates tab's separate upstream-update check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alan Wizemann
2026-05-07 11:51:05 +02:00
parent f9e3cd38f5
commit 3a3c87e033
3 changed files with 25 additions and 5 deletions
@@ -133,12 +133,20 @@ public struct SkillSnapshotDiff: Sendable, Equatable {
}
/// Compact label for the "What's New" pill, e.g.
/// "2 new, 4 updated since you last looked" or "1 new skill".
/// "2 new, 4 changed since you last looked" or "1 new skill".
///
/// Wording note (issue #78): we used to say "X updated since you
/// last looked" but the same screen also surfaces an "Updates"
/// sub-tab driven by `hermes skills check` (skills with newer
/// **upstream** versions available). Two surfaces with the word
/// "update" meaning two different things read as a contradiction
/// to the user. "Changed" describes the local file delta without
/// colliding with upstream-update vocabulary.
public var label: String {
switch (newCount, updatedCount) {
case (let n, 0): return n == 1 ? "1 new skill since you last looked" : "\(n) new skills since you last looked"
case (0, let u): return u == 1 ? "1 updated skill since you last looked" : "\(u) updated skills since you last looked"
default: return "\(newCount) new, \(updatedCount) updated since you last looked"
case (0, let u): return u == 1 ? "1 changed skill since you last looked" : "\(u) changed skills since you last looked"
default: return "\(newCount) new, \(updatedCount) changed since you last looked"
}
}
}
+6 -1
View File
@@ -48,7 +48,12 @@ struct SkillsView: View {
// picker when the per-server snapshot diff has changes.
// First-load with no prior snapshot silently primes (no
// pill, the snapshot just records what's there).
if let diff = snapshotDiff,
//
// Issue #78: scope the pill to the Installed tab. It
// describes local file deltas; rendering it on Updates
// contradicts the upstream-version-check pane below.
if currentTab == .installed,
let diff = snapshotDiff,
diff.hasChanges,
!diff.previousSnapshotEmpty {
whatsNewPill(diff: diff)
@@ -71,7 +71,14 @@ struct SkillsView: View {
// changes against a non-empty prior snapshot (first launch
// is silent so users aren't drowned in "everything is
// new!" noise).
if let diff = snapshotDiff,
//
// Issue #78: keep the pill scoped to the Installed tab.
// It describes local file deltas in the installed-skill
// tree; surfacing it above the Hub or Updates tab read as
// a contradiction with the Updates body's separate
// upstream-version check.
if currentTab == .installed,
let diff = snapshotDiff,
diff.hasChanges,
!diff.previousSnapshotEmpty {
whatsNewPill(diff: diff)