name: upgrade description: Intelligently upgrade claudesidian with new features while preserving user customizations using AI-powered semantic analysis. Use when the user wants to upgrade claudesidian, pull in upstream changes, or update their installation. allowed-tools: [Read, Write, Edit, MultiEdit, Bash, WebFetch, Grep, Glob]
Smart Upgrade
Pulls the latest claudesidian from GitHub and merges it into the user's vault, preserving customizations.
Layout assumptions (READ FIRST)
claudesidian stores skills under .agents/skills/<name>/SKILL.md as the
canonical location. Symlinks live at .claude/skills/<name> and
.pi/skills/<name> pointing back to canonical. Edit canonical, all consumers
follow.
If the user is on a pre-conversion claudesidian (anything before the
commands→skills migration) they will have .claude/commands/*.md instead and
no .agents/skills/. Do not run a normal upgrade in that case — see
"Migration from legacy layout" at the bottom of this file.
If the user's local repo has .agents/skills/ populated, proceed normally.
Process
1. Version check
- Read current version from
package.json - Fetch upstream version:
CURRENT=$(grep '"version"' package.json | head -1 | cut -d'"' -f4) LATEST=$(curl -s https://raw.githubusercontent.com/heyitsnoah/claudesidian/main/package.json | grep '"version"' | head -1 | cut -d'"' -f4) if [ "$CURRENT" = "$LATEST" ]; then echo "✅ Already on $CURRENT" exit 0 fi - Detect layout:
test -d .agents/skills && echo NEW || echo LEGACY. If LEGACY, jump to "Migration from legacy layout".
2. Backup
BACKUP_DIR=".backup/upgrade-$(date +%Y-%m-%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
cp -r .agents .claude .pi .scripts package.json "$BACKUP_DIR/" 2>/dev/null
cp CHANGELOG.md README.md "$BACKUP_DIR/" 2>/dev/null || true
echo "✅ Backup created at $BACKUP_DIR"
3. Fetch upstream
git clone --depth=1 --branch=main \
https://github.com/heyitsnoah/claudesidian.git \
.tmp/claudesidian-upgrade
The user's working repo stays disconnected from origin throughout — we only
ever read from .tmp/.
4. Build upgrade checklist
System files we care about:
- Skills:
.agents/skills/<name>/SKILL.md(canonical) — also resources inside skill dirs (helper scripts, references). - Hooks:
.claude/hooks/*.sh - Settings:
.claude/settings.json - MCP servers:
.claude/mcp-servers/* - Scripts:
.scripts/* - Core:
package.json,CHANGELOG.md,README.md
Files we never touch:
- User content folders:
00_Inbox/,01_Projects/,02_Areas/,03_Resources/,04_Archive/,05_Attachments/,06_Metadata/(except06_Metadata/Templates/if upstream changes them) - The user's
CLAUDE.md .obsidian/(user's Obsidian settings)vault-config.json.mcp.json(contains API keys)- Anything in
.git/
Build the checklist:
# Skills that exist in both, or only upstream, or only local
diff -qr .agents/skills .tmp/claudesidian-upgrade/.agents/skills 2>/dev/null
# Hooks, settings, mcp-servers, scripts
diff -qr .claude/hooks .tmp/claudesidian-upgrade/.claude/hooks 2>/dev/null
diff -q .claude/settings.json .tmp/claudesidian-upgrade/.claude/settings.json 2>/dev/null
diff -qr .claude/mcp-servers .tmp/claudesidian-upgrade/.claude/mcp-servers 2>/dev/null
diff -qr .scripts .tmp/claudesidian-upgrade/.scripts 2>/dev/null
# Core files
diff -q package.json .tmp/claudesidian-upgrade/package.json
diff -q README.md .tmp/claudesidian-upgrade/README.md
diff -q CHANGELOG.md .tmp/claudesidian-upgrade/CHANGELOG.md
Write findings to .upgrade-checklist.md, grouped by category, with status
markers [ ] pending, [x] updated, [-] skipped.
5. File-by-file review
Hard rules — do not skip:
- Always show the diff before modifying anything.
- Always wait for the user's choice. Never auto-pick.
- Never use
cp -f. Usecat src > destfor non-interactive overwrite. - Update
.upgrade-checklist.mdafter every file.
For each file in the checklist:
- Show
diff -u local upstream. - Determine state:
- No local edits, no upstream edits → mark
[-]skipped, move on. - Upstream changed, no local edits → ask: apply / keep / view full diff.
- Both changed (local customization) → ask: keep yours / take upstream / view full diff / AI-merge.
- No local edits, no upstream edits → mark
- Ask the user:
Wait for input. Do not auto-select.File: <path> has updates. 1. Apply update (take upstream) 2. Keep your version 3. View full diff 4. AI-merge Choice (1/2/3/4): - Apply the chosen action:
# Option 1 if [ -f ".tmp/claudesidian-upgrade/$path" ]; then mkdir -p "$(dirname "$path")" cat ".tmp/claudesidian-upgrade/$path" > "$path" echo "✅ Updated $path" fi - Mark in checklist and continue.
6. Symlink hygiene (skills only)
After updating any skill in .agents/skills/<name>/, verify the symlinks in
.claude/skills/<name> and .pi/skills/<name> still resolve:
for name in $(ls .agents/skills); do
for agent in claude pi; do
link=".${agent}/skills/${name}"
target="../../.agents/skills/${name}"
mkdir -p ".${agent}/skills"
if [ -L "$link" ]; then
# Symlink exists — verify it points to the right place
current="$(readlink "$link")"
if [ "$current" != "$target" ]; then
rm "$link"
ln -s "$target" "$link"
echo "✅ Repaired symlink $link (was → $current)"
fi
elif [ -e "$link" ]; then
# Real file or directory at this path — do not trample user data
echo "⚠️ $link exists as a real file/dir, not a symlink. Skipping."
echo " Manual fix: inspect, back up if needed, then rm and rerun."
else
# Nothing there — create
ln -s "$target" "$link"
echo "✅ Created symlink $link"
fi
done
done
The -L test is critical: a broken symlink (target missing) returns false from
-e but true from -L, so checking -e alone would try to ln -s over the
existing broken link and fail with "File exists". Conversely, a symlink
pointing the wrong way would pass -e (because the wrong target still exists)
and silently stay wrong. Always check -L first, then verify the target with
readlink, then fall through to -e for real files, then create if nothing
exists.
If upstream introduced a brand-new skill, this loop also creates its symlinks.
7. Verification
Re-run the diff commands from step 4. The only differences should be files the
user explicitly chose to keep (marked [-] or [x] customized in the
checklist). Anything still pending [ ] is a bug — report it and let the user
decide whether to retry.
8. Final steps
- Update
package.jsonversion to match upstream rm -rf .tmp/claudesidian-upgrade- Save the final
.upgrade-checklist.mdto the backup dir for reference - Print a summary: updated count, skipped count, customized count
Conflict resolution philosophy
When a skill has both upstream and local edits, prefer AI-merge over "take upstream." The user's local edit usually represents an intentional preference (their voice, their workflow conventions). The upstream edit usually represents a new feature or bug fix. Almost always you can keep both.
Show your merge proposal as a concrete diff before applying. Don't paraphrase.
Update categories
Auto-safe (low risk, default to "apply")
- Brand-new skills upstream introduced (additive — just symlink in)
- Hook script updates (
.claude/hooks/*.sh) when local hasn't changed package.jsondependency bumps independencies/devDependencies(preserve user-added scripts in thescriptssection)CHANGELOG.md(always replace with upstream version)- New files in
.scripts/
Needs review (always ask)
- Skills the user has touched
.claude/settings.json(often has user-added hooks)package.jsonscriptssectionREADME.md- MCP server files
Never touch
See the "files we never touch" list in step 4.
Error handling
- No internet → fail gracefully, suggest retry
- GitHub rate limit → wait + retry once, then fail with the rate-limit reset time
- Merge conflict during AI-merge → show both versions, ask user to pick
rm -rf .tmp/claudesidian-upgradefails → leave it, warn the user
Rollback
The backup directory from step 2 is the rollback target. Manual rollback:
cp -r .backup/upgrade-<timestamp>/.agents .
cp -r .backup/upgrade-<timestamp>/.claude .
cp .backup/upgrade-<timestamp>/package.json .
# etc.
Don't try to be clever with selective rollbacks — restore the whole snapshot.
Migration from legacy layout
If test -d .agents/skills returns false, the user is on a pre-conversion
claudesidian. Their skills live in .claude/commands/*.md. A normal upgrade
will not work — the diff will show every command as "removed locally" and
every skill as "added upstream."
The migration path:
Stop and explain. Tell the user their layout predates the commands→skills conversion and offer to migrate.
Backup first (step 2 above, but include
.claude/commands/).Move command files to skill dirs:
mkdir -p .agents/skills for f in .claude/commands/*.md; do [ -f "$f" ] || continue name=$(basename "$f" .md) [ "$name" = "README" ] && continue mkdir -p ".agents/skills/$name" mv "$f" ".agents/skills/$name/SKILL.md" doneAdd
name/descriptionfrontmatter to any file that lacks it. Use theadd-frontmatterskill.Create symlinks for
.claude/skills/and.pi/skills/(see step 6).Validate frontmatter. Use the
quick_validate.pyscript bundled with theskill-creatorskill in this repo:for d in .agents/skills/*/; do uv run --with pyyaml python \ .agents/skills/skill-creator/scripts/quick_validate.py "$d" doneThis enforces the full skill schema (name, description, allowed-tools, compatibility, license, metadata) and will reject any file with extra or missing required keys.
If
uvis not installed orskill-creatoris somehow missing, fall back to this minimal inline check that only verifiesnameanddescriptionare present:for f in .agents/skills/*/SKILL.md; do dir=$(basename "$(dirname "$f")") awk ' BEGIN { in_fm=0; has_name=0; has_desc=0 } /^---$/ { in_fm++; next } in_fm==1 && /^name:/ { has_name=1 } in_fm==1 && /^description:/ { has_desc=1 } END { if (!has_name) print " ✗ missing name" if (!has_desc) print " ✗ missing description" if (has_name && has_desc) print " ✓ ok" } ' "$f" | sed "s|^| $dir: |" doneThen run the normal upgrade flow to pull in any additional upstream changes.
This migration is one-time. After it runs successfully, future upgrades use the normal flow.
Selective upgrades
Common subset commands the user may ask for:
- "Just update skills" → only diff
.agents/skills/ - "Just dependencies" → only update
package.jsondeps - "Just hooks" → only diff
.claude/hooks/
Treat these as filters on the checklist. Same review/confirm rules apply.