Files
claude-skills/.wiki/source/build-notes.md
vitya 9f54068de0 feat: migrate 12 personal skills + add build/install scripts
- skills/: editable sources for all 12 personal skills (caveman family,
  find-skills, project-bootstrap, task-status-wiki, using-context7,
  using-markitdown, wiki-maintainer, compress)
- dist/: built .skill archives, committed (cross-machine deploy without
  needing zip on the target)
- scripts/build.sh + build.ps1: zip skills/<name>/ into dist/<name>.skill;
  Windows fallback uses .NET ZipArchive (PS 5.1 Compress-Archive writes
  backslashes that break extraction on *nix)
- scripts/install.sh: copy skills/<name>/ into ~/.claude/skills/<name>/
  ($CLAUDE_SKILLS_DIR overrides target)
- .wiki/source/repo-layout.md, build-notes.md: design + gotchas
- .gitignore: keep dist/ tracked

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 10:42:33 +03:00

1.9 KiB

Build Notes

Practical gotchas around building .skill archives.

Why build.ps1 exists alongside build.sh

The user is on Windows; the install target may be Linux/macOS. So archives must be portable.

Windows PowerShell 5.1's Compress-Archive (v1.0.1.0) writes ZIP entries with backslashes (e.g. caveman\SKILL.md). Linux/macOS unzip then either fails or extracts the literal name as a single file. Verified: archives produced by Compress-Archive listed entries like caveman\SKILL.md.

Workarounds considered:

  • Install zip.exe → adds a Windows dep we don't want.
  • PowerShell 7's Compress-Archive is fixed → can't assume PS7 is installed.
  • Use .NET System.IO.Compression.ZipArchive directly ← chosen. Walks files, adds entries with path -replace '\\','/'. Spec-compliant ZIPs everywhere.

build.ps1 does that. build.sh prefers zip (one-liner, fast on *nix), and on Windows-without-zip it falls back to invoking build.ps1 via powershell.exe.

ZIP layout the loader expects

Looking at the canonical ~/.claude/skills/<name>/ layout, the .skill archive should contain a single top-level directory <name>/ with SKILL.md plus optional assets/, references/, etc. inside.

zip -qr dist/<name>.skill <name> (run from skills/) does this naturally. The .NET path adds an explicit <name>/ prefix to each entry.

Extracting .skill files

A .skill file is just a renamed .zip. To extract on Windows:

Copy-Item project-bootstrap.skill project-bootstrap.zip
Expand-Archive -Path project-bootstrap.zip -DestinationPath ~/.claude/skills/
Remove-Item project-bootstrap.zip

On *nix: unzip dist/project-bootstrap.skill -d ~/.claude/skills/.

(Our install.sh skips this entirely — it copies from skills/ directly. Extraction-from-archive is only needed when you don't have the source tree, e.g. when sharing a single .skill file with someone else.)