upgrade skill
Upgrade the NotFair plugin to the latest version.
by nowork-studio·MIT license·★ 3,853 Stars on the repo·GitHub ↗
npx degit nowork-studio/notfair-plugin/notfair-upgrade-skill#main ~/.claude/skills/upgrade-nowork-studioChecked ·commit main
Files of upgrade
Show the full text190 lines
/notfair:upgrade
Upgrade the NotFair plugin to the latest version and show what's new.
Key paths
| 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) |
Inline upgrade flow
This section is used when a skill preamble outputs UPGRADE_AVAILABLE.
Step 1: Auto-upgrade
Log "Upgrading NotFair v{old} → v{new}..." and proceed to Step 2.
Step 2: Detect current install
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"
Step 3: Save old version
OLD_VERSION=$(cat "$INSTALLED_DIR/VERSION" 2>/dev/null | tr -d '[:space:]' || echo "unknown")
Step 4: Update marketplace repo and install
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.
Step 5: Update installed_plugins.json
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')
"
Step 6: Clean up old cache versions
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
done
Step 7: Write marker + clear update state
mkdir -p ~/.toprank
echo "$OLD_VERSION" > ~/.toprank/just-upgraded-from
rm -f ~/.toprank/last-update-check
rm -f ~/.toprank/update-snoozed
Step 8: Show What's New
Read $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.
Step 9: Continue
After showing What's New, continue with whatever skill the user originally invoked.
Dev symlink detection
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"
fi
If 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.
Standalone usage
When invoked directly as /notfair:upgrade:
Check for dev symlink (see "Dev symlink detection" above). If detected, stop.
Force a fresh update check (bypass cache and snooze):
_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"
If
UPGRADE_AVAILABLE <old> <new>: follow Steps 2–8 above.If no
UPGRADE_AVAILABLEoutput: tell the user "You're already on the latest version (v{LOCAL})."
| 1 | |
| 2 | name upgrade |
| 3 | argument-hint "<or just run '/notfair:upgrade'>" |
| 4 | description > |
| 5 | Upgrade the NotFair plugin to the latest version. Updates the marketplace repo, |
| 6 | installs the new version to the plugin cache, and updates installed_plugins.json. |
| 7 | Use when asked to "upgrade notfair", "update notfair", or "get latest version". |
| 8 | Also handles inline upgrade prompts when a skill detects UPGRADE_AVAILABLE at startup. |
| 9 | allowed-tools |
| 10 | - Bash |
| 11 | - Read |
| 12 | - AskUserQuestion |
| 13 | |
| 14 | |
| 15 | # /notfair:upgrade |
| 16 | |
| 17 | Upgrade the NotFair plugin to the latest version and show what's new. |
| 18 | |
| 19 | ## Key paths |
| 20 | |
| 21 | | What | Path | |
| 22 | |------|------| |
| 23 | | Marketplace repo | `~/.claude/plugins/marketplaces/nowork-studio/` | |
| 24 | | Plugin cache | `~/.claude/plugins/cache/nowork-studio/notfair/<version>/` | |
| 25 | | Installed plugins | `~/.claude/plugins/installed_plugins.json` | |
| 26 | | Update state | `~/.toprank/` (intentionally preserved — see CHANGELOG 0.24.0) | |
| 27 | |
| 28 | |
| 29 | |
| 30 | ## Inline upgrade flow |
| 31 | |
| 32 | This section is used when a skill preamble outputs `UPGRADE_AVAILABLE`. |
| 33 | |
| 34 | ### Step 1: Auto-upgrade |
| 35 | |
| 36 | Log "Upgrading NotFair v{old} → v{new}..." and proceed to Step 2. |
| 37 | |
| 38 | |
| 39 | |
| 40 | ### Step 2: Detect current install |
| 41 | |
| 42 | First check for dev symlink (see "Dev symlink detection" section). If detected, stop — do not upgrade. |
| 43 | |
| 44 | |
| 45 | # Find the currently installed plugin path |
| 46 | INSTALLED_DIR=$(ls -d ~/.claude/plugins/cache/nowork-studio/notfair/*/ 2>/dev/null | grep -v '.bak' | head -1) |
| 47 | if [ -z "$INSTALLED_DIR" ]; then |
| 48 | echo "ERROR: NotFair plugin not found in cache"; exit 1 |
| 49 | fi |
| 50 | MARKETPLACE_DIR="$HOME/.claude/plugins/marketplaces/nowork-studio" |
| 51 | if [ ! -d "$MARKETPLACE_DIR/.git" ]; then |
| 52 | echo "ERROR: marketplace repo not found at $MARKETPLACE_DIR"; exit 1 |
| 53 | fi |
| 54 | echo "Current install: $INSTALLED_DIR" |
| 55 | echo "Marketplace repo: $MARKETPLACE_DIR" |
| 56 | |
| 57 | |
| 58 | ### Step 3: Save old version |
| 59 | |
| 60 | |
| 61 | OLD_VERSION=$(cat "$INSTALLED_DIR/VERSION" 2>/dev/null | tr -d '[:space:]' || echo "unknown") |
| 62 | |
| 63 | |
| 64 | ### Step 4: Update marketplace repo and install |
| 65 | |
| 66 | |
| 67 | cd "$MARKETPLACE_DIR" |
| 68 | git fetch origin |
| 69 | git reset --hard origin/main |
| 70 | NEW_VERSION=$(cat VERSION | tr -d '[:space:]') |
| 71 | GIT_SHA=$(git rev-parse HEAD) |
| 72 | |
| 73 | # Create new versioned cache directory |
| 74 | NEW_CACHE_DIR="$HOME/.claude/plugins/cache/nowork-studio/notfair/$NEW_VERSION" |
| 75 | if [ -d "$NEW_CACHE_DIR" ]; then |
| 76 | rm -rf "$NEW_CACHE_DIR" |
| 77 | fi |
| 78 | mkdir -p "$NEW_CACHE_DIR" |
| 79 | |
| 80 | # Copy plugin files (exclude .git to save space) |
| 81 | rsync -a --exclude='.git' "$MARKETPLACE_DIR/" "$NEW_CACHE_DIR/" |
| 82 | |
| 83 | |
| 84 | If the copy fails, warn: "Upgrade failed — the old version is still active. Run `/notfair:upgrade` manually." and stop. |
| 85 | |
| 86 | ### Step 5: Update installed_plugins.json |
| 87 | |
| 88 | Read `~/.claude/plugins/installed_plugins.json`, then update the `notfair@nowork-studio` entry: |
| 89 | |
| 90 | |
| 91 | python3 -c " |
| 92 | import json, os |
| 93 | from datetime import datetime, timezone |
| 94 | |
| 95 | path = os.path.expanduser('~/.claude/plugins/installed_plugins.json') |
| 96 | with open(path) as f: |
| 97 | data = json.load(f) |
| 98 | |
| 99 | data['plugins']['notfair@nowork-studio'] = [{ |
| 100 | 'scope': 'user', |
| 101 | 'installPath': os.path.expanduser('~/.claude/plugins/cache/nowork-studio/notfair/$NEW_VERSION'), |
| 102 | 'version': '$NEW_VERSION', |
| 103 | 'installedAt': data['plugins'].get('notfair@nowork-studio', [{}])[0].get('installedAt', datetime.now(timezone.utc).isoformat()), |
| 104 | 'lastUpdated': datetime.now(timezone.utc).isoformat(), |
| 105 | 'gitCommitSha': '$GIT_SHA' |
| 106 | }] |
| 107 | |
| 108 | with open(path, 'w') as f: |
| 109 | json.dump(data, f, indent=4) |
| 110 | print('Updated installed_plugins.json: notfair@nowork-studio -> v$NEW_VERSION') |
| 111 | " |
| 112 | |
| 113 | |
| 114 | ### Step 6: Clean up old cache versions |
| 115 | |
| 116 | Remove old versioned cache directories (keep only the new one). Never remove a `dev` symlink: |
| 117 | |
| 118 | |
| 119 | for dir in ~/.claude/plugins/cache/nowork-studio/notfair/*/; do |
| 120 | ver=$(basename "$dir") |
| 121 | if [ "$ver" != "$NEW_VERSION" ] && [ "$ver" != "dev" ]; then |
| 122 | rm -rf "$dir" |
| 123 | echo "Removed old cache: $ver" |
| 124 | fi |
| 125 | done |
| 126 | |
| 127 | |
| 128 | ### Step 7: Write marker + clear update state |
| 129 | |
| 130 | |
| 131 | mkdir -p ~/.toprank |
| 132 | echo "$OLD_VERSION" > ~/.toprank/just-upgraded-from |
| 133 | rm -f ~/.toprank/last-update-check |
| 134 | rm -f ~/.toprank/update-snoozed |
| 135 | |
| 136 | |
| 137 | ### Step 8: Show What's New |
| 138 | |
| 139 | Read `$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. |
| 140 | |
| 141 | Format: |
| 142 | |
| 143 | NotFair v{new} — upgraded from v{old}! |
| 144 | |
| 145 | What's new: |
| 146 | - [bullet 1] |
| 147 | - [bullet 2] |
| 148 | - ... |
| 149 | |
| 150 | The new version will be fully active on your next Claude Code session. |
| 151 | |
| 152 | |
| 153 | ### Step 9: Continue |
| 154 | |
| 155 | After showing What's New, continue with whatever skill the user originally invoked. |
| 156 | |
| 157 | |
| 158 | |
| 159 | ## Dev symlink detection |
| 160 | |
| 161 | Before upgrading, check if the installed cache directory is a symlink named `dev`: |
| 162 | |
| 163 | |
| 164 | CACHE_DIR=$(ls -d ~/.claude/plugins/cache/nowork-studio/notfair/*/ 2>/dev/null | head -1) |
| 165 | if [ -L "${CACHE_DIR%/}" ] && [ "$(basename "$CACHE_DIR")" = "dev" ]; then |
| 166 | echo "DEV_SYMLINK" |
| 167 | fi |
| 168 | |
| 169 | |
| 170 | If `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. |
| 171 | |
| 172 | |
| 173 | |
| 174 | ## Standalone usage |
| 175 | |
| 176 | When invoked directly as `/notfair:upgrade`: |
| 177 | |
| 178 | Check for dev symlink (see "Dev symlink detection" above). If detected, stop. |
| 179 | |
| 180 | Force a fresh update check (bypass cache and snooze): |
| 181 | |
| 182 | _UPD_BIN=$(ls ~/.claude/plugins/cache/nowork-studio/notfair/*/bin/notfair-update-check 2>/dev/null | head -1) |
| 183 | [ -n "$_UPD_BIN" ] && _UPD=$("$_UPD_BIN" --force 2>/dev/null || true) || _UPD="" |
| 184 | echo "$_UPD" |
| 185 | |
| 186 | |
| 187 | If `UPGRADE_AVAILABLE <old> <new>`: follow Steps 2–8 above. |
| 188 | |
| 189 | If no `UPGRADE_AVAILABLE` output: tell the user "You're already on the latest version (v{LOCAL})." |
| 190 |
Discussion
Browse more free Claude skills.