upgrade — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited upgrade (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Upgrade the NotFair plugin to the latest version and show what's new.
| What | Path |
|---|---|
| Marketplace repo | ~/.claude/plugins/marketplaces/nowork-studio/ |
| Plugin cache | ~/.claude/plugins/cache/nowork-studio/notfair/<version>/ |
| Installed plugins | ~/.claude/plugins/installed_plugins.json |
| Update state | ~/.toprank/ (intentionally preserved — see CHANGELOG 0.24.0) |
This section is used when a skill preamble outputs UPGRADE_AVAILABLE.
Log "Upgrading NotFair v{old} → v{new}..." and proceed to Step 2.
First check for dev symlink (see "Dev symlink detection" section). If detected, stop — do not upgrade.
# Find the currently installed plugin path
INSTALLED_DIR=$(ls -d ~/.claude/plugins/cache/nowork-studio/notfair/*/ 2>/dev/null | grep -v '.bak' | head -1)
if [ -z "$INSTALLED_DIR" ]; then
echo "ERROR: NotFair plugin not found in cache"; exit 1
fi
MARKETPLACE_DIR="$HOME/.claude/plugins/marketplaces/nowork-studio"
if [ ! -d "$MARKETPLACE_DIR/.git" ]; then
echo "ERROR: marketplace repo not found at $MARKETPLACE_DIR"; exit 1
fi
echo "Current install: $INSTALLED_DIR"
echo "Marketplace repo: $MARKETPLACE_DIR"OLD_VERSION=$(cat "$INSTALLED_DIR/VERSION" 2>/dev/null | tr -d '[:space:]' || echo "unknown")cd "$MARKETPLACE_DIR"
git fetch origin
git reset --hard origin/main
NEW_VERSION=$(cat VERSION | tr -d '[:space:]')
GIT_SHA=$(git rev-parse HEAD)
# Create new versioned cache directory
NEW_CACHE_DIR="$HOME/.claude/plugins/cache/nowork-studio/notfair/$NEW_VERSION"
if [ -d "$NEW_CACHE_DIR" ]; then
rm -rf "$NEW_CACHE_DIR"
fi
mkdir -p "$NEW_CACHE_DIR"
# Copy plugin files (exclude .git to save space)
rsync -a --exclude='.git' "$MARKETPLACE_DIR/" "$NEW_CACHE_DIR/"If the copy fails, warn: "Upgrade failed — the old version is still active. Run /notfair:upgrade manually." and stop.
Read ~/.claude/plugins/installed_plugins.json, then update the notfair@nowork-studio entry:
python3 -c "
import json, os
from datetime import datetime, timezone
path = os.path.expanduser('~/.claude/plugins/installed_plugins.json')
with open(path) as f:
data = json.load(f)
data['plugins']['notfair@nowork-studio'] = [{
'scope': 'user',
'installPath': os.path.expanduser('~/.claude/plugins/cache/nowork-studio/notfair/$NEW_VERSION'),
'version': '$NEW_VERSION',
'installedAt': data['plugins'].get('notfair@nowork-studio', [{}])[0].get('installedAt', datetime.now(timezone.utc).isoformat()),
'lastUpdated': datetime.now(timezone.utc).isoformat(),
'gitCommitSha': '$GIT_SHA'
}]
with open(path, 'w') as f:
json.dump(data, f, indent=4)
print('Updated installed_plugins.json: notfair@nowork-studio -> v$NEW_VERSION')
"Remove old versioned cache directories (keep only the new one). Never remove a dev symlink:
for dir in ~/.claude/plugins/cache/nowork-studio/notfair/*/; do
ver=$(basename "$dir")
if [ "$ver" != "$NEW_VERSION" ] && [ "$ver" != "dev" ]; then
rm -rf "$dir"
echo "Removed old cache: $ver"
fi
donemkdir -p ~/.toprank
echo "$OLD_VERSION" > ~/.toprank/just-upgraded-from
rm -f ~/.toprank/last-update-check
rm -f ~/.toprank/update-snoozedRead $NEW_CACHE_DIR/CHANGELOG.md. Find all version entries between the old version and the new version. Summarize as 3-7 bullets grouped by theme — focus on user-facing changes, skip internal refactors.
Format:
NotFair v{new} — upgraded from v{old}!
What's new:
- [bullet 1]
- [bullet 2]
- ...
The new version will be fully active on your next Claude Code session.After showing What's New, continue with whatever skill the user originally invoked.
Before upgrading, check if the installed cache directory is a symlink named dev:
CACHE_DIR=$(ls -d ~/.claude/plugins/cache/nowork-studio/notfair/*/ 2>/dev/null | head -1)
if [ -L "${CACHE_DIR%/}" ] && [ "$(basename "$CACHE_DIR")" = "dev" ]; then
echo "DEV_SYMLINK"
fiIf DEV_SYMLINK: tell the user "NotFair is installed as a dev symlink — it always points to your local source (v$(cat "$CACHE_DIR/VERSION" 2>/dev/null | tr -d '[:space:]')). No upgrade needed." and stop. Do not proceed with Steps 2–8.
When invoked directly as /notfair:upgrade:
_UPD_BIN=$(ls ~/.claude/plugins/cache/nowork-studio/notfair/*/bin/notfair-update-check 2>/dev/null | head -1)
[ -n "$_UPD_BIN" ] && _UPD=$("$_UPD_BIN" --force 2>/dev/null || true) || _UPD=""
echo "$_UPD"UPGRADE_AVAILABLE <old> <new>: follow Steps 2–8 above.UPGRADE_AVAILABLE output: tell the user "You're already on the latest version (v{LOCAL})."~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.