fix: stale update banner after upgrade + skill sync dirty worktree crash
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful

Update checker: only cache registry latest version, always check installed
version fresh — fixes false "0.0.3 → 0.0.4" banner after upgrading.

Skill sync: use git status --porcelain for dirty detection (catches untracked
files), stash with --include-untracked, abort stale rebase on pull failure,
and print tip directing users to skills-local/ for persistent customizations.

Bump @mosaic/mosaic and @mosaic/cli to 0.0.5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jarvis
2026-04-02 21:02:53 -05:00
parent 381b0eed7b
commit 4b85395992
4 changed files with 62 additions and 29 deletions

View File

@@ -56,25 +56,39 @@ if [[ $fetch -eq 1 ]]; then
if [[ -d "$SKILLS_REPO_DIR/.git" ]]; then
echo "[mosaic-skills] Updating skills source: $SKILLS_REPO_DIR"
# Stash any local changes (dirty index or worktree) before pulling
local_changes=0
if ! git -C "$SKILLS_REPO_DIR" diff --quiet 2>/dev/null || \
! git -C "$SKILLS_REPO_DIR" diff --cached --quiet 2>/dev/null; then
local_changes=1
echo "[mosaic-skills] Stashing local changes..."
git -C "$SKILLS_REPO_DIR" stash push -q -m "mosaic-sync-skills auto-stash"
# Detect ANY dirty state: modified, staged, or untracked files.
# Use git status --porcelain which catches everything pull --rebase cares about.
dirty=""
dirty="$(git -C "$SKILLS_REPO_DIR" status --porcelain 2>/dev/null || true)"
if [[ -n "$dirty" ]]; then
echo "[mosaic-skills] Stashing local changes (including untracked)..."
git -C "$SKILLS_REPO_DIR" stash push -q --include-untracked -m "mosaic-sync-skills auto-stash" 2>/dev/null || {
echo "[mosaic-skills] WARN: stash failed — skipping pull, using existing checkout" >&2
dirty="skip-pull"
}
fi
if ! git -C "$SKILLS_REPO_DIR" pull --rebase; then
echo "[mosaic-skills] WARN: pull failed — continuing with existing checkout" >&2
if [[ "$dirty" != "skip-pull" ]]; then
if ! git -C "$SKILLS_REPO_DIR" pull --rebase 2>/dev/null; then
echo "[mosaic-skills] WARN: pull failed — continuing with existing checkout" >&2
# Abort any in-progress rebase so the repo isn't left in a broken state
git -C "$SKILLS_REPO_DIR" rebase --abort 2>/dev/null || true
fi
fi
# Restore stashed changes
if [[ $local_changes -eq 1 ]]; then
# Restore stashed changes if we stashed anything
if [[ -n "$dirty" && "$dirty" != "skip-pull" ]]; then
echo "[mosaic-skills] Restoring local changes..."
git -C "$SKILLS_REPO_DIR" stash pop -q 2>/dev/null || \
echo "[mosaic-skills] WARN: stash pop had conflicts — check $SKILLS_REPO_DIR" >&2
fi
# Hint: customized skills belong in skills-local/, not in the canonical repo
if [[ -n "$dirty" ]]; then
echo "[mosaic-skills] TIP: Put customized skills in $MOSAIC_LOCAL_SKILLS_DIR/ instead"
echo "[mosaic-skills] Files there are never overwritten and take precedence."
fi
else
echo "[mosaic-skills] Cloning skills source to: $SKILLS_REPO_DIR"
mkdir -p "$(dirname "$SKILLS_REPO_DIR")"