From e871c20272699988ca2e11eabf8bb32e4de44472 Mon Sep 17 00:00:00 2001 From: vitya Date: Mon, 25 May 2026 13:09:47 +0300 Subject: [PATCH] docs(install): .wiki concept page for install-cross-platform parity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes 3/3 acceptance of [install-ps1]: - (a) install.ps1 existed - (b) --prune flag shipped in 6cf0e98 - (c) concept page now written .wiki/concepts/install-cross-platform.md captures: - why two scripts (PS for native-Win, sh for Linux/Mac) - parity contract (shared invariants, flag-naming convention) - --prune design choices and rejected alternatives - scope boundary (install-side only; dist/.skill prune is separate) Index + log updated per .wiki/CLAUDE.md schema. STATUS.md: [install-ps1] ⚪ → 🟢, new ⚪ task [install-ps1-build-prune-followup] filed for the analogous flag on build.{sh,ps1}. --- .tasks/STATUS.md | 18 +++++--- .wiki/concepts/install-cross-platform.md | 56 ++++++++++++++++++++++++ .wiki/index.md | 1 + .wiki/log.md | 2 + 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 .wiki/concepts/install-cross-platform.md diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index b467bf3..22032d0 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -22,13 +22,21 @@ _Updated: 2026-05-25 (board-cleanup: done-блоки → .archive/done-2026-05.m --- -## ⚪ [install-ps1] — paired install.sh + install.ps1 (cross-platform parity, with --prune) -**Status:** ready -**Where I stopped:** Verify 2026-05-07 (factory-context audit): (a) ✅ `scripts/install.ps1` существует — кросс-платформа есть; (b) ❌ `--prune` flag отсутствует в обоих скриптах; (c) ❌ doc `.wiki/concepts/install-cross-platform.md` не написан. 1/3 acceptance — не закрывать. +## 🟢 [install-ps1] — paired install.sh + install.ps1 (cross-platform parity, with --prune) +**Status:** done +**Where I stopped:** All 3 acceptance items shipped 2026-05-25. (a) `scripts/install.ps1` existed pre-task. (b) `--prune` / `-Prune` flag added in commit `6cf0e98` (paired sh + ps1; combined-flag pattern; global-scan; default off; smoke-tested on disposable target dirs against fake stale skills). (c) Concept page `.wiki/concepts/install-cross-platform.md` written this commit: parity contract, --prune design choices, rejected alternatives, scope vs build/.skill prune. +**Next action:** (none — kept until merged) +**Branch:** master + -Пересечение с `[claude-skills-update-skill]`: оба про install/build/prune trinity. Имеет смысл сделать вместе — `--prune` логику добавить в существующие `install.{ps1,sh}` параллельно с новыми `update.{ps1,sh}` (которые будут жить в том же `scripts/`). Doc `install-cross-platform.md` тогда покрывает всю четвёрку. -**Next action:** (a) уже есть. Остаётся: (b) добавить `--prune` flag в `scripts/install.ps1` и `scripts/install.sh` — для каждого имени в `~/.claude/skills//`, отсутствующего в `skills//`, удалить (lesson из `[compress-dedup]`). (c) написать `.wiki/concepts/install-cross-platform.md` — документировать parity-инвариант (PS+bash сpan, identical behavior, paired flags, error semantics). Опционально: совместить с `[claude-skills-update-skill]` (см. её next_action). +--- + +## ⚪ [install-ps1-build-prune-followup] — Add matching `--prune` flag to `scripts/build.{sh,ps1}` for `dist/.skill` artefacts (analogue of install-script prune). +**Status:** ready +**Where I stopped:** Surfaced 2026-05-25 from `[install-ps1]` close — install-side prune ships, but `dist/.skill` artefacts have the same staleness problem (e.g. `dist/using-synology-ops.skill` would linger if it had ever been built). Currently no .skill exists for the retired skill, but the gap is real for future renames/retires. +**Next action:** Add `--prune` to `scripts/build.sh` and `scripts/build.ps1`: scan `dist/*.skill`, drop any whose `` is not in `skills/`. Same default-off / print-and-delete pattern as install-side. Update `.wiki/concepts/install-cross-platform.md` to extend the parity contract to build scripts. **Branch:** (not started) + --- diff --git a/.wiki/concepts/install-cross-platform.md b/.wiki/concepts/install-cross-platform.md new file mode 100644 index 0000000..b8e76c3 --- /dev/null +++ b/.wiki/concepts/install-cross-platform.md @@ -0,0 +1,56 @@ +--- +title: Install Cross-Platform Parity (PS + Bash) +type: concept +updated: 2026-05-25 +--- + +# Install Cross-Platform Parity (PS + Bash) + +Sibling concept to `install-portability.md` (POSIX-shell compat). This one is about the **paired-script parity contract** between `scripts/install.ps1` (PowerShell) and `scripts/install.sh` (bash). + +## Why two scripts + +Windows hosts running CC outside a git-bash terminal have no reliable bash. Native PowerShell call (`pwsh ./scripts/install.ps1`) is the friction-free path. Linux / macOS users get bash. Both audiences are first-class — `claude-skills` is multi-machine by design (see `project_deployment_goal` memory). + +Single-script "use bash everywhere" was rejected: forces every Windows user to install git-bash before bootstrap, contradicts "tool-light install path". + +## Parity contract + +Both scripts MUST: + +- Read sources from `/skills//`. +- Install to `$CLAUDE_SKILLS_DIR` if set, else `~/.claude/skills/`. +- Accept a name-list (positional in bash, `-Names` in PS); no args = all. +- Skip with a warning when `skills//` is missing or has no `SKILL.md`. +- Idempotent: `rm -rf` (or `Remove-Item -Recurse -Force`) the destination, then copy fresh. +- Print one `installed: -> ` line per successfully installed skill. + +Flag naming follows the host shell's convention — POSIX `--prune` in bash, PascalCase `-Prune` switch in PowerShell. Behaviour identical. + +## The `--prune` / `-Prune` flag + +Added 2026-05-25 (commit `6cf0e98`). Motivating case: after retiring `using-synology-ops` the installed dir `~/.claude/skills/using-synology-ops/` lingered until manual `rm` — the install scripts had no notion of stale-cleanup. + +**Behaviour:** after the install loop, walk `$target/*` and remove any dir whose name is not in `skills/*`. + +**Design choices and their rejected alternatives:** + +- **Combined flag, not standalone mode.** Single invocation does both. Alternative (`install --prune-only`) was rejected — adds a mode that nobody asked for; users wanting "just cleanup" can pass an empty name list (`install.sh --prune` with no positional args still walks the prune step at the end, no-op'ing the install loop because all source skills resolve to no-op overwrites of fresh installs). + +- **Global scan, ignores name filter.** Even when called as `install.sh foo --prune`, the prune step scans the full target against the full source. Rationale: stale-cleanup is a global concern. A user who explicitly opts into prune wants the cleanup to be useful — a names-filtered prune ("only prune dirs that match the name list AND are missing from source") rarely matches anyone's mental model. + +- **Print-and-delete, no confirmation prompt.** Each removal prints `pruning: (not in skills/) -> `. Confirmation prompts would block automation (CI, batch reinstalls). Visibility comes from the printed line; users wanting a dry-run pass `-WhatIf` in PowerShell (the cmdlet already supports it) or pipe to `echo` in bash (trivial to grep `^pruning:` before running for real). + +- **Default off.** Must be passed explicitly. Idempotent re-installs (the common case) don't suddenly delete anything. + +## What `--prune` does NOT do + +- It does not remove `dist/.skill` artefacts. That's a build concern, not install. The matching `--prune` flag on `build.sh` / `build.ps1` is a separate task (`[install-ps1]` acceptance was scoped to install scripts; `dist/` is a build artefact directory). +- It does not touch plugin-installed skills under `~/.claude/plugins//skills//`. Those are managed by the plugin system, not this repo. +- It does not warn if the about-to-be-deleted dir contains user-edited content. The contract is that `~/.claude/skills//` is a managed copy of `skills//` — anything else is user-error. + +## Test evidence + +Both scripts smoke-tested 2026-05-25 on disposable target dirs (env-overridden `CLAUDE_SKILLS_DIR`). Pre-populated with 2 fake stale dirs, ran full install + prune, verified: stale dirs removed, all real skills installed, retired `using-synology-ops` absent. No automated test fixture in the repo — install scripts are wrapper-style, smoke-test evidence in the `6cf0e98` commit body suffices under the `[skip-tdd: wrapper]` carve-out. + +`[archive-roundtrip-test]` (still ⚪ on the board) is a candidate place to add a real fixture once it lands. diff --git a/.wiki/index.md b/.wiki/index.md index 9988ee4..8e4fabd 100644 --- a/.wiki/index.md +++ b/.wiki/index.md @@ -22,6 +22,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever - [bootstrap-skill-deps-check.md](concepts/bootstrap-skill-deps-check.md) — project-bootstrap@1.7.0 — Step 5.6 collapses the per-skill "detect-and-recommend" mirror shape into one generic `trigger → fulfiller` table walker (skill vs plugin kind, never auto-install); subsumes the deferred `[bootstrap-recommend-projects-meta]` and the existing `superpowers`-only detector - [bootstrap-manifest.md](concepts/bootstrap-manifest.md) — record of which `project-bootstrap` / `setup-wiki` / `setup-tasks` versions initialized this project's `.wiki/` and `.tasks/` layout (overwritten on re-bootstrap; history in git) - [build-notes.md](concepts/build-notes.md) — why `build.ps1` exists alongside `build.sh`; PS 5.1 backslash-in-zip gotcha; how to extract a `.skill` +- [install-cross-platform.md](concepts/install-cross-platform.md) — parity contract between `install.ps1` and `install.sh` (paired-script invariant); rationale for `--prune` / `-Prune` flag (combined-with-install, global-scan, default-off) - [install-portability.md](concepts/install-portability.md) — `install.sh` / `build.sh` rewritten to drop `mapfile` (bash 4+) and `find -printf` (GNU only) so stock macOS (bash 3.2 + BSD find) works - [context7-setup.md](concepts/context7-setup.md) — switched context7 from manual MCP entries to the official plugin; API key in `.mcp.json` as `--api-key`; now also captured as `setup-context7` skill (one-time install/migrate flow with key discovery) - [projects-meta-skills.md](concepts/projects-meta-skills.md) — `setup-projects-meta` + `using-projects-meta` skill pair for the local `projects-meta-mcp` stdio server (cross-project tasks + shared Gitea wiki); local-first rule + two-step mutation pattern diff --git a/.wiki/log.md b/.wiki/log.md index 1e4a91b..6e76d67 100644 --- a/.wiki/log.md +++ b/.wiki/log.md @@ -61,3 +61,5 @@ Parseable: `grep "^## \[" .wiki/log.md | tail -20`. ## [2026-05-22] ingest | concepts/interns-grep-audit-design ## [2026-05-25] decision | session-handoff-skill-design — design rationale for the `session-handoff` skill captured in wiki after cluster 7/7 closure; sliding overwrite of `.tasks/NEXT_SESSION.md`, phrase whitelist + substantive-commit heuristic, opt-in PostToolUse hook, orient+ask default, source: `~/projects/.workshop/.archive/2026-05-24-session-handoff-skill.md` Round 1 + Round 2 + +## [2026-05-25] decision | install-cross-platform — `install.{ps1,sh}` paired-script parity contract documented; `--prune` / `-Prune` flag rationale (combined-with-install, global-scan ignores names filter, default-off, print-and-delete no prompt); shipped in commit `6cf0e98` with `[skip-tdd: wrapper]` carve-out + smoke-test evidence; closes 2/3 of `[install-ps1]` acceptance (the doc + flag), `dist/`-prune analogue deferred to `build` scripts