docs(install): .wiki concept page for install-cross-platform parity
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}.
This commit is contained in:
@@ -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)
|
## 🟢 [install-ps1] — paired install.sh + install.ps1 (cross-platform parity, with --prune)
|
||||||
**Status:** ready
|
**Status:** done
|
||||||
**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 — не закрывать.
|
**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
|
||||||
|
<!-- closed-by: vitya@DESKTOP-NSEF0UK / 2026-05-25 / 3/3 acceptance met; build-script analogue for dist/.skill prune remains separate concern -->
|
||||||
|
|
||||||
Пересечение с `[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/<name>/`, отсутствующего в `skills/<name>/`, удалить (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/<name>.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/<name>.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 `<name>` 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)
|
**Branch:** (not started)
|
||||||
|
<!-- created-by: vitya@DESKTOP-NSEF0UK / 2026-05-25 / origin: [install-ps1] close — natural extension to build scripts -->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
56
.wiki/concepts/install-cross-platform.md
Normal file
56
.wiki/concepts/install-cross-platform.md
Normal file
@@ -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 `<repo>/skills/<name>/`.
|
||||||
|
- 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/<name>/` is missing or has no `SKILL.md`.
|
||||||
|
- Idempotent: `rm -rf` (or `Remove-Item -Recurse -Force`) the destination, then copy fresh.
|
||||||
|
- Print one `installed: <name> -> <path>` 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: <name> (not in skills/) -> <path>`. 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/<name>.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/<plugin>/skills/<name>/`. 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/<name>/` is a managed copy of `skills/<name>/` — 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.
|
||||||
@@ -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-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)
|
- [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`
|
- [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
|
- [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)
|
- [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
|
- [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
|
||||||
|
|||||||
@@ -61,3 +61,5 @@ Parseable: `grep "^## \[" .wiki/log.md | tail -20`.
|
|||||||
## [2026-05-22] ingest | concepts/interns-grep-audit-design
|
## [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 | 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
|
||||||
|
|||||||
Reference in New Issue
Block a user