Compare commits

..

2 Commits

Author SHA1 Message Date
cec2b8b61c meta(tasks): close [claude-skills-update-skill] — shipped v0.1.0 + PS 5.1 bugfix
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 15:33:18 +03:00
0a8d8acaa1 fix(update.ps1): replace Unicode with ASCII + null-safety for PS 5.1
PowerShell 5.1 on Russian Windows reads .ps1 files as ANSI (CP1251),
breaking em dashes and box-drawing characters in comments/strings.
Also fix NullArray error when Select-String finds no version match.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 15:30:25 +03:00
2 changed files with 26 additions and 54 deletions

View File

@@ -574,39 +574,13 @@ Pre-commit hooks have `--no-verify`. Per `project-discipline` Rule 4 («never sk
---
## [claude-skills-update-skill] — Orchestrator-скил `update-claude-skills` — Claude-Code-сторона аналог `hermes-installer-skill`. Триггеры: «обнови claude-skills», «sync claude-skills», «update claude-skills», «обнови всё». На Windows + Claude Code (а также Linux/Mac) прогоняет в одну команду полный uplift существующей установки:
## 🟢 [claude-skills-update-skill] — Orchestrator-скил `update-claude-skills` — Claude-Code-сторона аналог `hermes-installer-skill`. Триггеры: «обнови claude-skills», «sync claude-skills», «update claude-skills», «обнови всё». На Windows + Claude Code (а также Linux/Mac) прогоняет в одну команду полный uplift существующей установки:
1. `git pull --ff-only` в `~/projects/claude-skills/` (если репа есть; иначе подсказать `git clone`).
2. `git pull` + `npm run build` в `~/projects/.common/lib/projects-meta-mcp/` — только если изменения в source.
3. `git pull` + `pip install -e .` в `~/projects/.common/lib/interns-mcp/` — только если изменения.
4. `pwsh ./scripts/install.ps1` (или `bash ./scripts/install.sh` на Linux/Mac) → копия скилов в `~/.claude/skills/`.
5. Дифф skill versions — прочитать `version:` frontmatter до/после, показать что поменялось.
6. Если MCP-source пересобран — напомнить `/reload-mcp`.
7. Если появились новые setup-скилы (`setup-foo`) — предложить запустить (но не запускать сам — оставить юзеру).
Cross-platform: PowerShell-ветка + bash-ветка (как у `install.ps1`/`install.sh`). Скил версионируется per discipline Rule 3.
Корневая боль: на Claude-Code-стороне сейчас обновление claude-skills — это `git pull && install.ps1 && /reload-mcp` плюс ручные setup-* при появлении нового MCP. На N машинах это N×ручной ритуал на каждое обновление каталога. `hermes-installer-skill` (⚪ ready в этой же репе) закрывает Hermes-сторону. После обоих — раскатка claude-skills на любую машину превращается в одну фразу.
Возможное пересечение с `factory-bootstrap` (проект `factory`, промоутнут 2026-05-06): выяснить scope-границу до начала работы. Если factory покрывает «инициализация машины с нуля до рабочего Claude Code» — этот скил фокусируется только на uplift существующей установки, не дублируя greenfield-bootstrap.
**Status:** ready
**Where I stopped:** **Приоритизировано 2026-05-07** — high priority, следующая для пика. После трёх живых incident'ов на stostayer.new машине, каждый из которых был ритуалом «обновить claude-skills на удалённой машине»:
1. **Bootstrap upgrade-mode false-positive** на claude-skills (template-литерал не имел tdd-criteria + recommend-dont-menu). Зафиксили через `[bootstrap-fix-tdd-recommend-template]` ✅ → v1.10.1.
2. **`setup-interns` отсутствие clone-fallback** (skill bail-out на missing source) → `[setup-interns-clone-fallback]` + `[setup-interns-fix-paths]` ✅ → setup-interns v0.3.0.
3. **`projects-meta-mcp` legacy standalone-install** на той машине + `npm install` не запускался при ручной миграции (silent skip из-за отсутствия node_modules).
Каждый раз ритуал: 1) git pull claude-skills 2) install.ps1 на конкретный изменённый skill 3) для MCP-серверов `cd .common/lib/<server> ; npm install ; npm run build` 4) `/reload-plugins`. На N машинах = N×ритуал на каждую правку. Все три incident'а были бы избежаны если бы на той машине жил скил `update-claude-skills`, выполняющий ровно эти 4 шага автоматом.
Дополнительный gain: при следующем добавлении нового MCP-сервера в `.common/lib/` (3-й, 4-й, ...) — нужна нулевая дополнительная работа на удалённых машинах. update-claude-skills скил детектит «появилась новая subdir в `.common/lib/<name>/` с pyproject.toml или package.json», предлагает запустить соответствующий setup-* (если есть в каталоге), либо просто билдит и не регистрирует (если setup-skill ещё не написан).
**Рекомендую** делать одной сессией в `~/projects/claude-skills/` — спека полная, scope узкий, ничего не блокирует.
**Next action:** ⚠️ **ARCH-note (2026-05-07, после ревизии `.factory/factory.yaml`):** таска НЕ дубликат factory L1 — она Layer 2 citizen в дизайне factory. `factory.yaml` line 83-91 уже включает `claude-skills` как компонент с `post_install: 'bash {target}/scripts/install.sh'`. **Recommended shape (вариант B с оглядкой на A):** реальная update-логика — в `scripts/update.{ps1,sh}` (рядом с `install.{ps1,sh}`), один источник истины. Скил `update-claude-skills` — короткий wrapper, на триггер вызывает нужный скрипт по `active-platform`. Когда L1 Go-бинарь дойдёт — `factory update` использует те же скрипты без duplication.
1) Скрипты: `scripts/update.ps1` + `scripts/update.sh` в корне репы. Логика: pull/build/install в трёх местах (claude-skills + .common/lib/projects-meta-mcp + .common/lib/interns-mcp), version-diff, reload-hint. **Возможность совмещения с `[install-ps1]`:** добавить `--prune` flag сразу в `update.{ps1,sh}` и в `install.{ps1,sh}` (там 1 of 3 criteria из install-ps1). 2) Скил-структура: `skills/update-claude-skills/SKILL.md`, frontmatter `version: 0.1.0`, описание с триггерами («обнови claude-skills», «sync claude-skills»). Скил — wrapper, не содержит логику. 3) Build + install: `pwsh ./scripts/build.ps1 update-claude-skills`, `pwsh ./scripts/install.ps1 update-claude-skills`. 4) Smoke на текущей машине — должно быть no-op (всё свежее, идемпотентность). 5) Mapping в `hermes/mapping.yaml` (`mode: skip` — Claude-Code-only) или `mode: manual` если параллельно делаем Hermes-twin (логика та же, но Hermes-side скрипт другой — там не install.sh а skill_manage). 6) Обновить `.factory/factory.yaml` post_install: `bash {target}/scripts/update.sh` (или `pwsh ... update.ps1` если factory детектит OS) — отдельный 1-line PR в `.factory`. 7) Doc `.wiki/concepts/claude-skills-update-flow.md` (опционально слить с `install-cross-platform.md` из `[install-ps1]`). 8) `tasks_close`.
**Branch:** n/a
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: meeting-room / 2026-05-07T07:42:04.462Z -->
**Status:** done
**Where I stopped:** Shipped в `627a183 feat(update-claude-skills): add update skill + scripts [v0.1.0]`. Bugfix в `0a8d8ac` — PS 5.1 Unicode crash (em dashes + box-drawing в ANSI-CP1251) + NullArray на Select-String miss. Scripts `scripts/update.{ps1,sh}` + SKILL.md v0.1.0 (wrapper, delegates to active-platform). Smoke verified: idempotent no-op on current machine. Hermes mapping: `mode: skip` (Claude-Code-only). Dist archive built + installed.
**Next action:** (none — kept until merged). Follow-ups: (1) `.factory/factory.yaml` post_install → `update.sh` — отдельный PR в factory; (2) `--prune` flag — tracked in `[install-ps1]`; (3) wiki doc `claude-skills-update-flow.md` — optional, can merge with `install-cross-platform.md`.
**Branch:** master
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: meeting-room / 2026-05-07T07:42:04.462Z; closed: 2026-05-07 from claude-skills -->
---

View File

@@ -1,4 +1,4 @@
# update.ps1 Full uplift cycle for claude-skills on Windows (PowerShell)
# update.ps1 -- Full uplift cycle for claude-skills on Windows (PowerShell)
#
# Steps:
# 1. git pull --ff-only in claude-skills repo
@@ -9,7 +9,7 @@
# 6. Print reload hints
#
# Usage: update.ps1 [-Yes]
# -Yes skip confirmation prompts (assume yes)
# -Yes -- skip confirmation prompts (assume yes)
[CmdletBinding()]
param(
@@ -18,7 +18,7 @@ param(
$ErrorActionPreference = 'Stop'
# ── Paths ──────────────────────────────────────────────────────────────────
# -- Paths -------------------------------------------------------------------
$root = Split-Path -Parent $PSScriptRoot
$skillsSrc = Join-Path $root 'skills'
@@ -28,22 +28,21 @@ $commonRoot = if ($env:COMMON_ROOT) { $env:COMMON_ROOT } else { Join-Path $env:U
$metaMcp = Join-Path $commonRoot 'lib\projects-meta-mcp'
$internsMcp = Join-Path $commonRoot 'lib\interns-mcp'
# ── Collect before-versions ────────────────────────────────────────────────
# -- Collect before-versions --------------------------------------------------
$beforeVersions = @{}
if (Test-Path $target) {
Get-ChildItem -Path $target -Directory | ForEach-Object {
Get-ChildItem -Path $target -Directory -ErrorAction SilentlyContinue | 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 = '?' }
$match = Select-String -Path $vf -Pattern '^version:\s*(\d+\.\d+\.\d+)' -ErrorAction SilentlyContinue | Select-Object -First 1
$ver = if ($match) { $match.Matches.Groups[1].Value } else { '?' }
$beforeVersions[$_.Name] = $ver
}
}
}
# ── Step 1: git pull ────────────────────────────────────────────────────────
# -- Step 1: git pull ---------------------------------------------------------
Write-Host "`n[update] Pulling claude-skills repo..." -ForegroundColor Cyan
Push-Location $root
@@ -70,11 +69,11 @@ 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
Write-Host "[warn] Could not pop stash -- resolve manually" -ForegroundColor Yellow
}
}
# ── Step 2: projects-meta-mcp ─────────────────────────────────────────────
# -- Step 2: projects-meta-mcp -----------------------------------------------
$mcpRebuilt = $false
@@ -101,10 +100,10 @@ if (Test-Path (Join-Path $metaMcp '.git')) {
}
Pop-Location
} else {
Write-Host "[warn] projects-meta-mcp not found at $metaMcp skipping." -ForegroundColor Yellow
Write-Host "[warn] projects-meta-mcp not found at $metaMcp -- skipping." -ForegroundColor Yellow
}
# ── Step 3: interns-mcp ───────────────────────────────────────────────────
# -- Step 3: interns-mcp -----------------------------------------------------
if (Test-Path (Join-Path $internsMcp '.git')) {
Write-Host "[update] Checking interns-mcp..." -ForegroundColor Cyan
@@ -127,26 +126,25 @@ if (Test-Path (Join-Path $internsMcp '.git')) {
}
Pop-Location
} else {
Write-Host "[warn] interns-mcp not found at $internsMcp skipping." -ForegroundColor Yellow
Write-Host "[warn] interns-mcp not found at $internsMcp -- skipping." -ForegroundColor Yellow
}
# ── Step 4: Install skills ─────────────────────────────────────────────────
# -- 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 ───────────────────────────────────────────────────
# -- Step 5: Version diff -----------------------------------------------------
Write-Host "[update] Version diff:" -ForegroundColor Cyan
$changes = $false
Get-ChildItem -Path $target -Directory | ForEach-Object {
Get-ChildItem -Path $target -Directory -ErrorAction SilentlyContinue | 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 = '?' }
$match = Select-String -Path $vf -Pattern '^version:\s*(\d+\.\d+\.\d+)' -ErrorAction SilentlyContinue | Select-Object -First 1
$after = if ($match) { $match.Matches.Groups[1].Value } else { '?' }
$before = $beforeVersions[$_.Name]
if (-not $before) { $before = 'new' }
if ($before -ne $after) {
@@ -159,7 +157,7 @@ if (-not $changes) {
Write-Host ' (no version changes)'
}
# ── Step 6: New setup-skills hint ──────────────────────────────────────────
# -- Step 6: New setup-skills hint -------------------------------------------
$newSetup = @()
Get-ChildItem -Path $skillsSrc -Directory | ForEach-Object {
@@ -176,7 +174,7 @@ if ($newSetup.Count -gt 0) {
Write-Host ' Run the setup skill to configure it.'
}
# ── Step 7: Reload hints ──────────────────────────────────────────────────
# -- Step 7: Reload hints ----------------------------------------------------
Write-Host ''
Write-Host '[ok] Update complete!' -ForegroundColor Green