From skill-sommelier
Create a single-line install script with auto-update capability for CLI tools, Python packages, or applications. Generates shell scripts similar to uv or uw-s3 installers that handle installation, configuration, and optional dependencies. Use when users want to "create an install script", "make a single-line installer", "add auto-update", or "build an installer like uv". Triggers on "install script", "single-line installer", "curl installer", "auto-update script", "installer like uv", "install.sh".
How this skill is triggered — by the user, by Claude, or both
Slash command
/skill-sommelier:ss-install-scriptThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Create production-ready single-line install scripts with auto-update capabilities.
Create production-ready single-line install scripts with auto-update capabilities.
curl -LsSf URL | shUnderstand what needs to be installed and how.
Ask the user or infer from context:
uv tool install, cargo install, pip install)Read the project's README if available to understand existing install instructions
Exit: Clear understanding of installation requirements.
Select the appropriate template based on project type.
| Project Type | Template | Features |
|---|---|---|
| Python package (uv) | uv-tool | uv tool install, config files, optional deps |
| Rust binary | cargo | cargo install, binary placement, config |
| Shell script | script | Download script, make executable, PATH setup |
| Generic | generic | Flexible installer with auto-update |
Exit: Template selected.
Create scripts/install.sh based on the chosen template.
Use the template from references/templates.md
Customize these sections:
Ensure the script:
set -eu for error handling (or set -euo pipefail if #!/bin/bash)/dev/tty for interactive prompts, gated by a TTY check so CI installs don't hang--yes / INSTALLER_ASSUME_YES=1 for unattended installs (see "Non-Interactive Mode" in references/templates.md)For binary downloads, verify a checksum before extracting/installing. See "Checksum Verification" in references/templates.md. tar tzf only detects corruption, not tampering.
Prefer deferring credential prompts to first run rather than asking during curl | sh. Install-time prompts break unattended installs, can end up in shell history, and put secrets through a piped subshell. Inline credential prompts are only appropriate when the tool is unusable without them and no first-run UX exists.
Exit: scripts/install.sh created and tested.
Create scripts/uninstall.sh as a standard companion artifact. Every mature installer (uv, rustup, rclone, brew) ships one — without it, users can't cleanly remove your tool.
Use the "Uninstall Template" in references/templates.md. It should:
uv tool uninstall / cargo uninstall$XDG_CONFIG_HOME/PROJECT) — prompt unless --purge is passedExit: scripts/uninstall.sh created.
Create an update mechanism. Default: built-in self-update subcommand.
For any tool you control the source of (Python via uv tool, Rust via cargo, compiled binary with a release pipeline), add a <tool> update or <tool> self-update subcommand. This is what uv, rustup, and gh all do.
references/self-update-patterns.mdWhy this is the default: discoverable via --help, no second file to maintain, no shell pipe required at update time, lives in the codebase under version control.
scripts/update.sh — use when the tool is a pure shell script with no "source code" to add a subcommand to, or when the install is git-clone-based and git pull is the natural update path. See Pattern 2.Exit: A built-in update subcommand exists, or an explicit reason was recorded for choosing an alternative.
Add installation instructions to README.
Add an "Install" section with two one-liners — a pinned production install and a tracking install:
## Install
Pinned to the latest release (recommended):
```bash
curl -LsSf https://raw.githubusercontent.com/USER/REPO/v1.0.0/scripts/install.sh | sh
```
Tracking `main` (for contributors / bleeding edge):
```bash
curl -LsSf https://raw.githubusercontent.com/USER/REPO/main/scripts/install.sh | sh
```
The installer will set up `<command>`, prompt for configuration, and handle dependencies.
Why two: the main URL re-fetches whatever the latest commit is at the time the user runs it — that means a compromised or accidentally-broken commit on main ships to everyone who runs curl | sh until you notice. Pinning to a tag (or commit SHA) freezes what users execute. README copy should default to the pinned URL and only mention main as a contributor option.
Bump the pinned version in the README on every release. The ssm-repo-release skill is a good place to wire this in.
Document what the installer does:
Add manual install instructions as fallback
Exit: README updated with clear install instructions.
Verify the script works in a clean environment.
Test in a fresh shell or container:
docker run -it --rm ubuntu:22.04 bash
# Then run the curl installer
Verify:
Test edge cases:
Exit: Installer tested and working.
Listed roughly in order of impact:
raw.githubusercontent.com/.../main/install.sh is mutable — anyone with push access (or a compromised dependency that touches the repo) can change what curl | sh users execute. See Phase 5 for the two-URL pattern.tar tzf only catches corruption. Publish a .sha256 next to each release asset and check it in the installer. See the "Checksum Verification" template.chmod 600).curl | sh.rclone.org/install.sh). Download to a temp file and bash <file> rather than piping.See references/examples.md for complete examples:
npx claudepluginhub jasonlo/skill-sommelierGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.