New skill and cross-platform scripts that automate the full uplift cycle: git pull → conditionally rebuild MCP servers → install skills → version diff → reload hints. Claude-Code-only (Hermes uses hermes-installer-skill). - scripts/update.sh: bash version (Linux/macOS/git-bash) - scripts/update.ps1: PowerShell version (Windows) - skills/update-claude-skills/SKILL.md: thin wrapper, detects platform - hermes/mapping.yaml: mode: skip (Claude-Code-only) - dist/update-claude-skills.skill: built archive - .tasks/STATUS.md: task marked done Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
186 lines
7.3 KiB
PowerShell
186 lines
7.3 KiB
PowerShell
# update.ps1 — Full uplift cycle for claude-skills on Windows (PowerShell)
|
|
#
|
|
# Steps:
|
|
# 1. git pull --ff-only in claude-skills repo
|
|
# 2. Conditionally rebuild projects-meta-mcp (if source changed)
|
|
# 3. Conditionally rebuild interns-mcp (if source changed)
|
|
# 4. Install all skills via install.ps1
|
|
# 5. Show version diff (before -> after)
|
|
# 6. Print reload hints
|
|
#
|
|
# Usage: update.ps1 [-Yes]
|
|
# -Yes — skip confirmation prompts (assume yes)
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[switch]$Yes
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# ── Paths ──────────────────────────────────────────────────────────────────
|
|
|
|
$root = Split-Path -Parent $PSScriptRoot
|
|
$skillsSrc = Join-Path $root 'skills'
|
|
$target = if ($env:CLAUDE_SKILLS_DIR) { $env:CLAUDE_SKILLS_DIR } else { Join-Path $env:USERPROFILE '.claude\skills' }
|
|
|
|
$commonRoot = if ($env:COMMON_ROOT) { $env:COMMON_ROOT } else { Join-Path $env:USERPROFILE 'projects\.common' }
|
|
$metaMcp = Join-Path $commonRoot 'lib\projects-meta-mcp'
|
|
$internsMcp = Join-Path $commonRoot 'lib\interns-mcp'
|
|
|
|
# ── Collect before-versions ────────────────────────────────────────────────
|
|
|
|
$beforeVersions = @{}
|
|
if (Test-Path $target) {
|
|
Get-ChildItem -Path $target -Directory | ForEach-Object {
|
|
$vf = Join-Path $_.FullName 'SKILL.md'
|
|
if (Test-Path $vf) {
|
|
$ver = (Select-String -Path $vf -Pattern '^version:\s*(\d+\.\d+\.\d+)' |
|
|
Select-Object -First 1).Matches.Groups[1].Value
|
|
if (-not $ver) { $ver = '?' }
|
|
$beforeVersions[$_.Name] = $ver
|
|
}
|
|
}
|
|
}
|
|
|
|
# ── Step 1: git pull ────────────────────────────────────────────────────────
|
|
|
|
Write-Host "`n[update] Pulling claude-skills repo..." -ForegroundColor Cyan
|
|
Push-Location $root
|
|
|
|
$dirty = git status --porcelain 2>$null
|
|
if ($LASTEXITCODE -ne 0) { $dirty = $true }
|
|
if ($dirty) {
|
|
Write-Host "[warn] Working tree has uncommitted changes. Stashing..." -ForegroundColor Yellow
|
|
git stash push -m 'update-ps1-auto-stash'
|
|
if ($LASTEXITCODE -ne 0) { Write-Error "Cannot stash changes"; Pop-Location; exit 1 }
|
|
$stashed = $true
|
|
} else {
|
|
$stashed = $false
|
|
}
|
|
|
|
git pull --ff-only
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "git pull --ff-only failed (diverged or no upstream)"
|
|
Pop-Location; exit 1
|
|
}
|
|
Write-Host "[ok] Repo updated." -ForegroundColor Green
|
|
|
|
if ($stashed) {
|
|
Write-Host "[update] Popping stashed changes..." -ForegroundColor Cyan
|
|
git stash pop 2>$null
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "[warn] Could not pop stash — resolve manually" -ForegroundColor Yellow
|
|
}
|
|
}
|
|
|
|
# ── Step 2: projects-meta-mcp ─────────────────────────────────────────────
|
|
|
|
$mcpRebuilt = $false
|
|
|
|
if (Test-Path (Join-Path $metaMcp '.git')) {
|
|
Write-Host "[update] Checking projects-meta-mcp..." -ForegroundColor Cyan
|
|
Push-Location $metaMcp
|
|
$preSha = git rev-parse HEAD
|
|
git pull --ff-only 2>$null
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "[warn] projects-meta-mcp: pull failed or no upstream" -ForegroundColor Yellow
|
|
}
|
|
$postSha = git rev-parse HEAD
|
|
|
|
if ($preSha -ne $postSha) {
|
|
Write-Host "[update] Source changed, rebuilding projects-meta-mcp..." -ForegroundColor Cyan
|
|
npm run build 2>$null
|
|
if ($LASTEXITCODE -ne 0) {
|
|
npm install; npm run build
|
|
}
|
|
Write-Host "[ok] projects-meta-mcp rebuilt." -ForegroundColor Green
|
|
$mcpRebuilt = $true
|
|
} else {
|
|
Write-Host "[ok] projects-meta-mcp: up to date." -ForegroundColor Green
|
|
}
|
|
Pop-Location
|
|
} else {
|
|
Write-Host "[warn] projects-meta-mcp not found at $metaMcp — skipping." -ForegroundColor Yellow
|
|
}
|
|
|
|
# ── Step 3: interns-mcp ───────────────────────────────────────────────────
|
|
|
|
if (Test-Path (Join-Path $internsMcp '.git')) {
|
|
Write-Host "[update] Checking interns-mcp..." -ForegroundColor Cyan
|
|
Push-Location $internsMcp
|
|
$preSha = git rev-parse HEAD
|
|
git pull --ff-only 2>$null
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Host "[warn] interns-mcp: pull failed or no upstream" -ForegroundColor Yellow
|
|
}
|
|
$postSha = git rev-parse HEAD
|
|
|
|
if ($preSha -ne $postSha) {
|
|
Write-Host "[update] Source changed, reinstalling interns-mcp..." -ForegroundColor Cyan
|
|
pip install -e . 2>$null
|
|
if ($LASTEXITCODE -ne 0) { pip3 install -e . }
|
|
Write-Host "[ok] interns-mcp reinstalled." -ForegroundColor Green
|
|
$mcpRebuilt = $true
|
|
} else {
|
|
Write-Host "[ok] interns-mcp: up to date." -ForegroundColor Green
|
|
}
|
|
Pop-Location
|
|
} else {
|
|
Write-Host "[warn] interns-mcp not found at $internsMcp — skipping." -ForegroundColor Yellow
|
|
}
|
|
|
|
# ── Step 4: Install skills ─────────────────────────────────────────────────
|
|
|
|
Pop-Location
|
|
Write-Host "[update] Installing skills..." -ForegroundColor Cyan
|
|
& "$root\scripts\install.ps1"
|
|
Write-Host "[ok] Skills installed." -ForegroundColor Green
|
|
|
|
# ── Step 5: Version diff ───────────────────────────────────────────────────
|
|
|
|
Write-Host "[update] Version diff:" -ForegroundColor Cyan
|
|
$changes = $false
|
|
Get-ChildItem -Path $target -Directory | ForEach-Object {
|
|
$vf = Join-Path $_.FullName 'SKILL.md'
|
|
if (Test-Path $vf) {
|
|
$after = (Select-String -Path $vf -Pattern '^version:\s*(\d+\.\d+\.\d+)' |
|
|
Select-Object -First 1).Matches.Groups[1].Value
|
|
if (-not $after) { $after = '?' }
|
|
$before = $beforeVersions[$_.Name]
|
|
if (-not $before) { $before = 'new' }
|
|
if ($before -ne $after) {
|
|
Write-Host " $before -> $after ($($_.Name))"
|
|
$changes = $true
|
|
}
|
|
}
|
|
}
|
|
if (-not $changes) {
|
|
Write-Host ' (no version changes)'
|
|
}
|
|
|
|
# ── Step 6: New setup-skills hint ──────────────────────────────────────────
|
|
|
|
$newSetup = @()
|
|
Get-ChildItem -Path $skillsSrc -Directory | ForEach-Object {
|
|
$name = $_.Name
|
|
if ($name -like 'setup-*' -and -not (Test-Path (Join-Path $target $name))) {
|
|
$newSetup += $name
|
|
}
|
|
}
|
|
|
|
if ($newSetup.Count -gt 0) {
|
|
Write-Host ''
|
|
Write-Host '[update] New setup skills available:' -ForegroundColor Cyan
|
|
$newSetup | ForEach-Object { Write-Host " - $_" }
|
|
Write-Host ' Run the setup skill to configure it.'
|
|
}
|
|
|
|
# ── Step 7: Reload hints ──────────────────────────────────────────────────
|
|
|
|
Write-Host ''
|
|
Write-Host '[ok] Update complete!' -ForegroundColor Green
|
|
if ($mcpRebuilt) {
|
|
Write-Host ' -> Run /reload-mcp to reload MCP servers (source changed)'
|
|
}
|
|
Write-Host ' -> Start a new Claude session for skill changes to take full effect' |