agentleFS
AirMileAirMile/claude-config/skills/core-update/SKILL.md

core-update

Skill0 starsChanged 4 months agoMITView on GitHub

Pull latest claude-config and rebuild ~/.claude/ files. Use with /core-update.

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 4 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Check jq availability (advisory only):

    line 48
  2. Very specific:

    Check for active git operations (rebase/merge/cherry-pick):

    line 54
  3. Distinctive:

    If any found → stop:

    line 63
  4. Distinctive:

    Check dirty working tree:

    line 102
  5. Distinctive:

    If fetch fails → stop:

    line 137
  6. Distinctive:

    If conflicts → show conflicting files, stop:

    line 147
  7. Very specific:

    If stashed in PHASE 1: git -C "$CONFIG_REPO" stash apply now.

    line 165
  8. Very specific:

    Always rebuild, regardless of whether any local/ files changed.

    line 171

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Core Update

Pull the latest claude-config and rebuild the composed global files.

Trigger: /core-update


PHASE 0: Pre-flight

Resolve CONFIG_REPO — same logic as core-bootstrap:

# macOS/Linux
if [ -L "$HOME/.claude/skills" ]; then
  CONFIG_REPO="$(realpath "$HOME/.claude/skills/..")"
else
  echo "error: ~/.claude/skills symlink not found. Run /core-bootstrap first." && exit 1
fi
# Windows
if (Test-Path "$env:USERPROFILE\.claude\skills" -PathType Container) {
  $CONFIG_REPO = Split-Path (Resolve-Path "$env:USERPROFILE\.claude\skills") -Parent
} else {
  Write-Error "~\.claude\skills junction not found. Run /core-bootstrap first."
  exit 1
}

Validate $CONFIG_REPO is a git repo:

git -C "$CONFIG_REPO" rev-parse --git-dir >/dev/null 2>&1 || \
  { echo "error: $CONFIG_REPO is not a git repository." && exit 1; }

Check jq availability (advisory only):

command -v jq >/dev/null 2>&1 || echo "warn: jq not found — settings overlay merge will be skipped"

Check for active git operations (rebase/merge/cherry-pick):

ls "$CONFIG_REPO/.git/rebase-merge" \
   "$CONFIG_REPO/.git/rebase-apply" \
   "$CONFIG_REPO/.git/MERGE_HEAD" \
   "$CONFIG_REPO/.git/CHERRY_PICK_HEAD" 2>/dev/null

If any found → stop:

Active git operation detected in claude-config repo. Resolve it first (git rebase --continue / --abort), then re-run /core-update.

Capture current Language: from ~/.claude/CLAUDE.md before any overwrite:

# macOS/Linux
CURRENT_LANG=$(grep "^Language:" "$HOME/.claude/CLAUDE.md" 2>/dev/null | sed 's/^Language: //')
[ -z "$CURRENT_LANG" ] && CURRENT_LANG="English"
# Windows
$currentLang = (Select-String -Path "$env:USERPROFILE\.claude\CLAUDE.md" -Pattern "^Language:" |
  Select-Object -First 1).Line -replace "^Language: ", ""
if (-not $currentLang) { $currentLang = "English" }

PHASE 1: Git status

Detect branch and upstream:

# macOS/Linux
BRANCH=$(git -C "$CONFIG_REPO" rev-parse --abbrev-ref HEAD)
UPSTREAM=$(git -C "$CONFIG_REPO" rev-parse --abbrev-ref @{u} 2>/dev/null || echo "")
[ -z "$UPSTREAM" ] && echo "warn: no upstream configured for branch $BRANCH — pull may fail"
# Windows
$branch = git -C $CONFIG_REPO rev-parse --abbrev-ref HEAD
$upstream = git -C $CONFIG_REPO rev-parse --abbrev-ref "@{u}" 2>$null
if (-not $upstream) { Write-Warning "No upstream configured for branch $branch — pull may fail" }

Check dirty working tree:

git -C "$CONFIG_REPO" status --porcelain

If dirty → AskUserQuestion:

  • header: "Uncommitted changes"
  • question: "claude-config has uncommitted changes. What would you like to do?"
  • options:
    • label: "Stash (Recommended)", description: "Stash changes, pull, then re-apply"
    • label: "Cancel", description: "Stop — I'll handle this myself"
  • multiSelect: false

On Stash: git -C "$CONFIG_REPO" stash push -u -m "core-update auto-stash". Continue with PHASE 2. After successful pull: git -C "$CONFIG_REPO" stash apply. On apply success → git -C "$CONFIG_REPO" stash drop. On conflict → report ("Stash conflict after pull — resolve manually with git stash list") and continue with rebuild anyway.

On Cancel → exit.

Store pre-pull ref:

PRE_REF=$(git -C "$CONFIG_REPO" rev-parse HEAD)

PHASE 2: Git pull

Fetch first (fail-fast on network issues):

git -C "$CONFIG_REPO" fetch 2>&1

If fetch fails → stop:

Fetch failed — check network connection or remote access. ~/.claude/ was not modified.

Pull:

git -C "$CONFIG_REPO" pull --rebase

If conflicts → show conflicting files, stop:

Pull resulted in conflicts. Resolve with \git rebase --continue` or `--abort`, then re-run /core-update.`

Store post-pull ref and count pulled commits:

POST_REF=$(git -C "$CONFIG_REPO" rev-parse HEAD)
COMMITS_PULLED=$(git -C "$CONFIG_REPO" rev-list --count "$PRE_REF".."$POST_REF")

Detect which config files changed in this pull:

CHANGED_LOCAL=$(git -C "$CONFIG_REPO" diff --name-only "$PRE_REF" "$POST_REF" -- local/ 2>/dev/null | wc -l | tr -d ' ')
CHANGED_SKILLS=$(git -C "$CONFIG_REPO" diff --name-only "$PRE_REF" "$POST_REF" -- skills/ agents/ hooks/ 2>/dev/null | wc -l | tr -d ' ')

If stashed in PHASE 1: git -C "$CONFIG_REPO" stash apply now. On apply success → git -C "$CONFIG_REPO" stash drop. On conflict → report and continue.


PHASE 3: Rebuild composed files

Always rebuild, regardless of whether any local/ files changed. This keeps composed files in sync even when the pull was "already up to date".

3a. Rebuild ~/.claude/CLAUDE.md

# macOS/Linux
cp "$CONFIG_REPO/local/CLAUDE.md.base" "$HOME/.claude/CLAUDE.md"
sed -i.bak "s/^Language:.*$/Language: $CURRENT_LANG/" "$HOME/.claude/CLAUDE.md" && rm -f "$HOME/.claude/CLAUDE.md.bak"
# Windows
Copy-Item "$CONFIG_REPO\local\CLAUDE.md.base" "$env:USERPROFILE\.claude\CLAUDE.md"
(Get-Content "$env:USERPROFILE\.claude\CLAUDE.md") -replace '^Language:.*$', "Language: $currentLang" |
  Set-Content "$env:USERPROFILE\.claude\CLAUDE.md"

3b. Rebuild ~/.claude/settings.json

# macOS/Linux
cp "$CONFIG_REPO/local/settings.json.template" "$HOME/.claude/settings.json"
# Windows
Copy-Item "$CONFIG_REPO\local\settings.json.template" "$env:USERPROFILE\.claude\settings.json"

3c. Rebuild ~/.claude/keybindings.json and ~/.claude/statusline-command.cjs

Simple overwrites — no merge needed, these files have no user customisation.

# macOS/Linux
cp "$CONFIG_REPO/local/keybindings.json" "$HOME/.claude/keybindings.json"
cp "$CONFIG_REPO/local/statusline-command.cjs" "$HOME/.claude/statusline-command.cjs"
# Windows
Copy-Item "$CONFIG_REPO\local\keybindings.json" "$env:USERPROFILE\.claude\keybindings.json"
Copy-Item "$CONFIG_REPO\local\statusline-command.cjs" "$env:USERPROFILE\.claude\statusline-command.cjs"

3d. Apply personal overlay

# macOS/Linux
PERSONAL_DIR="$CONFIG_REPO/personal"
OVERLAY_COUNT=0

if [ -d "$PERSONAL_DIR" ]; then
  if [ -f "$PERSONAL_DIR/CLAUDE.md.overlay" ]; then
    cat "$PERSONAL_DIR/CLAUDE.md.overlay" >> "$HOME/.claude/CLAUDE.md"
    OVERLAY_COUNT=$((OVERLAY_COUNT + 1))
  fi

  if [ -f "$PERSONAL_DIR/settings.overlay.json" ]; then
    if command -v jq >/dev/null 2>&1; then
      jq -s '.[0] * .[1]' "$HOME/.claude/settings.json" "$PERSONAL_DIR/settings.overlay.json" \
        > "$HOME/.claude/settings.json.tmp" && mv "$HOME/.claude/settings.json.tmp" "$HOME/.claude/settings.json"
      OVERLAY_COUNT=$((OVERLAY_COUNT + 1))
    else
      echo "warn: jq not found — skipping settings overlay merge"
    fi
  fi

  # styles/ symlink: skip — already linked by /core-bootstrap, idempotent
fi
# Windows
$personalDir = "$CONFIG_REPO\personal"
$overlayCount = 0

if (Test-Path $personalDir) {
  $overlay = "$personalDir\CLAUDE.md.overlay"
  if (Test-Path $overlay) {
    Get-Content $overlay | Add-Content "$env:USERPROFILE\.claude\CLAUDE.md"
    $overlayCount++
  }

  $settingsOverlay = "$personalDir\settings.overlay.json"
  if (Test-Path $settingsOverlay) {
    if (Get-Command jq -ErrorAction SilentlyContinue) {
      $merged = jq -s '.[0] * .[1]' "$env:USERPROFILE\.claude\settings.json" $settingsOverlay
      $merged | Set-Content "$env:USERPROFILE\.claude\settings.json"
      $overlayCount++
    } else {
      Write-Warning "jq not found — skipping settings overlay merge"
    }
  }
}

PHASE 3.5: Project schema migration check

Detect projects still on the pre-v2 .project/ schema (legacy marker: backlog.html exists, or project.json without schemaVersion):

ls -d {projects_root}/*/.project/backlog.html 2>/dev/null
  • No hits → skip silently.
  • Hits → AskUserQuestion: "Found {N} project(s) on the pre-v2 .project/ schema: {names}. Migrate now?" — "Yes, migrate all (Recommended)" / "Pick which" / "Skip". Per chosen project run:

    python3 "$CONFIG_REPO/scripts/migrate-project.py" {projects_root}/{name}

    The script is idempotent (re-runs are no-ops) and can also be run standalone at any time. Add the per-project result lines to the PHASE 4 report.


PHASE 4: Report

Update complete
══════════════════════════════════════════════════════
 Item                          Status
──────────────────────────────────────────────────────
 Branch                        dev ← origin/dev
 Commits pulled                3
 Config files changed          2 (in local/)
 Skills / agents updated       7
 ~/.claude/CLAUDE.md           rebuilt
 ~/.claude/settings.json       rebuilt
 ~/.claude/keybindings.json    rebuilt
 ~/.claude/statusline-…        rebuilt
 Personal overlay              applied (2 items)
 Language                      Nederlands (preserved)
══════════════════════════════════════════════════════
  • Commits pulled: show count. If 0 → "0 (already up to date)"
  • Config files changed: count from PHASE 2 CHANGED_LOCAL. If 0 → "0 (no base changes)"
  • Skills / agents updated: count from PHASE 2 CHANGED_SKILLS. If 0 → "0"
  • Personal overlay: "applied (N items)" / "not found (optional)" / "found, nothing to apply"
  • Language: show preserved value, e.g. Nederlands (preserved)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.