About install-script-generator
Install Script Generator is a skill for generating cross-platform installers and their supporting documentation for software projects. It plans dependencies, dry-runs an installation plan, and guides validation before producing an installer.
Key features
- 01Plans installation steps and dependencies
- 02Generates a bash installer for a single-command install
- 03Optionally generates a Windows PowerShell installer
- 04Creates a user-facing usage guide
- 05Validates script syntax and placeholders
Use cases
- 01Providing a one-command installer for a project
- 02Preparing installation scripts for supported operating systems
- 03Documenting installation steps and prerequisites
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ luongnv89/ skills --skill install-script-generatorAfter installing, type/install-script-generatorin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
docs/README.mdevals/evals.jsonreferences/edge-cases.mdfinal-report.mdinstall-template.mdreadme-snippet.mdscripts/doc_generator.pyenv_explorer.pyexecutor.pyplan_generator.pyDetails
From the project READMEInstall Script Generator
Generate robust, cross-platform installation scripts that users can run with a single bash command via GitHub raw URLs. This SKILL.md is a lean index — long templates and tables live under references/ to protect the agent's context budget.
When to Use
- The user asks for a
curl | bashone-liner for their project. - A repo needs a
install.shthat auto-detects OS, arch, and package manager. - A Python/Go/Node/Rust module should be installable in one command from a fresh machine.
Skip this skill for Dockerfiles, CI/CD pipelines, or one-off local shell scripts.
Prerequisites
- The repo has a known
<owner>/<repo>(checkgit remote -v) and a default branch. - The target software's build system is identifiable (
Makefile,package.json,setup.py,Cargo.toml,go.mod, etc.). python3is available locally for the helper scripts underscripts/. Ifpython3is missing, skip each helper-script step, record it asnot run (python3 not found), and continue; the run then endsPARTIAL.
Reference Files (read on demand to save tokens)
| File | When to read |
|---|---|
references/install-template.md | When generating install.sh — full bash template with detection helpers, dependency installer, and main entry point |
references/readme-snippet.md | When updating the README — copy-paste install block plus URL format notes |
references/edge-cases.md | When handling unusual OS/sudo/path scenarios and writing step reports |
references/final-report.md | When writing the final report — the four parts, status rules, outcome table, examples, reader checks |
scripts/env_explorer.py | Local environment probe (OS, arch, package managers, sudo) |
scripts/plan_generator.py | Generates installation_plan.yaml from env + target |
scripts/executor.py | Dry-runs installation_plan.yaml with rollback, before Phase 3 generation |
scripts/doc_generator.py | Renders user-facing USAGE_GUIDE.md |
Do not inline these contents into the conversation; link to them to preserve the context window.
Repo Sync Before Edits (mandatory)
Run this once, before Phase 1. Before creating, updating, or deleting files in an existing repo, sync the current branch with remote:
branch="$(git rev-parse --abbrev-ref HEAD)"
git fetch origin
git pull --rebase origin "$branch"
If the working tree is dirty, git stash push -u -m pre-sync first, sync, then git stash pop. If origin is missing or rebase/stash conflicts occur, stop and ask the user before continuing.
Workflow
A fix attempt is one edit followed by a rerun of the failed check. Stop after 3 fix attempts on the same check, record the check as failed, and continue to the next phase. To stop with BLOCKED, skip the remaining phases and print the final report.
Phase 1 — Exploration
- Identify the target software/module/tool. If the user did not name it and the repo holds more than one buildable project, ask which one.
- Inspect the repo for build files (
Makefile,package.json,setup.py,Cargo.toml,go.mod, ...). - Record the install method: the package name, if the target is published in a package manager, or the build-and-copy commands from its build file. If neither exists, ask the user. If the user gives no install method, stop with
BLOCKED. - List dependencies the software needs to build and run.
- Run
git remote get-url originto read<owner>/<repo>. - Run
git symbolic-ref --short refs/remotes/origin/HEADand striporigin/to read the default branch. - If step 5 or step 6 fails, ask the user for the value. If the user gives no answer, stop with
BLOCKED. - Run
python3 scripts/env_explorer.pyto capture OS, arch, package managers, shell, and sudo availability intoenv_info.json.
Phase 2 — Planning
- Order the dependencies so each one installs before anything that needs it.
- For each dependency, note the
command -v <dep>checkinstall.shuses to skip one that is already installed. - Run
python3 scripts/plan_generator.py --target "<name>" --env-file env_info.json --deps <dep1> <dep2> ...(dependencies from step 1, space-separated; omit--depsonly if there are none) to emitinstallation_plan.yaml. - If the target is not published in the detected package manager, edit the
Install <name>step ininstallation_plan.yaml: setcommand,verify, androllbackto the commandsinstall_<tool>will run. - Replace every
# TODOplaceholder in the plan. Add a step for each dependency thatplan_generator.pywarned it left out. - Run
python3 scripts/executor.py --plan installation_plan.yaml --dry-run. - Check the dry run: it exits 0, its last summary line starts
DRY RUN:, stderr has noplaceholder commandwarning, the steps follow the step 1 order, and everyInstall ...step has a non-nullrollback. The package-manager check and final verify steps carryrollback: nullby design. If a check fails, fix the plan and rerun step 6.
The dry run skips execution, so it checks the plan's shape, not that installation or rollback actually works.
Phase 3 — Generation (primary output)
If install.sh already exists at the repo root, show the user the planned changes and ask before overwriting it. If the user declines, stop with BLOCKED.
Generate install.sh at the repo root using references/install-template.md. The template contains four sections you compose:
- Header + colour helpers (
info,ok,warn,err,die). - Detection helpers (
detect_os,detect_arch,detect_package_manager,need_sudo). install_depsswitch covering apt/dnf/yum/pacman/brew/zypper.install_<tool>(customised per target),verify_installation, andmain.
Read references/install-template.md for the exact code; do not paste it into chat. If Windows support is needed, also generate install.ps1 (one-liner: irm <raw_url> | iex).
Then check the script. If a check fails, fix install.sh and rerun that check:
bash -n install.shexits 0.grep -nE '<owner>|<repo>|<branch>|<software_name>|<Software Name>|install_<tool>' install.shprints nothing.- If
shellcheckis on PATH,shellcheck -S error install.shexits 0. Otherwise recordshellcheck not run (not on PATH).
Do not run install.sh on the user's machine: it installs software and may call sudo. Run it only when the user asks for a local run or approves a disposable container. When it runs, its last line must be [ OK ] Installation complete!.
Phase 4 — Documentation
- Insert the install block from
references/readme-snippet.mdinto the project README, substituting<owner>/<repo>/<branch>. If the repo has no README, createREADME.mdholding only that block. - Run
python3 scripts/doc_generator.py --target "<name>" --plan installation_plan.yamlto emitUSAGE_GUIDE.md. - Run
grep -n "raw.githubusercontent.com/<owner>/<repo>/<branch>/install.sh" <README>with the real values; it must print one or more lines. - If
git ls-tree --name-only origin/<branch> install.shprintsinstall.sh, runcurl -fsSI <raw-url>and record the HTTP status. Otherwise recordraw URL not live until install.sh is pushed. - Print the final report.
Final Report
Print it once, as plain text in the chat, after the last Step Completion Report. Four parts, in order: Result: (status, target, one-liner), Evidence: (only checks that ran, with results), Uncertainty: (untested behavior, including install.sh was not executed), and Decision: (the approval needed, or No approval needed., then the push and cleanup actions). Read references/final-report.md for each part's contents, the outcome table, and examples.
Apply the first status rule that matches:
BLOCKED — <reason>—install.shwas not written.PARTIAL — <reason>—install.shwas written, and a required check failed or did not run:bash -n, the placeholdergrep,shellcheck -S error(when on PATH), the Phase 2 dry run, the README one-liner,USAGE_GUIDE.md, or an approved run ofinstall.shthat did not end with[ OK ] Installation complete!.COMPLETE— every required check passed.COMPLETEdoes not meaninstall.shran.
Output Files
| File | Description |
|---|---|
install.sh | Primary output — standalone installer for curl | bash |
install.ps1 | Optional Windows PowerShell installer |
USAGE_GUIDE.md | User-facing docs |
env_info.json | Local environment probe (working file) |
installation_plan.yaml | Ordered install steps (working file) |
install_report.md | Dry-run report from executor.py (working file) |
The three working files hold this machine's home path and PATH. Do not commit them unless the user asks; list them under Decision: for cleanup.
Acceptance Criteria
install.shexists at repo root, starts with#!/usr/bin/env bashandset -euo pipefail, and passes the three Phase 3 checks.- Auto-detects OS, architecture, and package manager; exits non-zero with a clear message on unsupported targets.
- Handles
sudogracefully (root, sudo, or fail-fast). - Verifies the installation at the end (
command -v $TOOL_NAMEplus--versionwhen available). - README contains a
curl -sSL ... | bashone-liner that points at the raw GitHub URL for<owner>/<repo>/<branch>. - When
install.shruns successfully, its last line is[ OK ] Installation complete!. - The final report opens with
Result:and a status from the rules above, and meets the four reader checks inreferences/final-report.md: result findable, facts apart from assumptions, claims traceable, next decision clear.
Edge Cases
See references/edge-cases.md for the full list. Highlights:
- Unsupported OS / architecture —
diewith the detected value; user sees what failed. - No package manager —
install_depsaborts withUnsupported package manager 'unknown'. - No sudo —
need_sudoexits withRequires root. Run as root or install sudo. - Windows native — generate
install.ps1separately;install.shwarns under MSYS/Cygwin. - Script in subdirectory — adjust the raw URL path; note it in the README snippet.
- Target not in a package manager — edit its plan step (Phase 2 step 4) and write
install_<tool>from the build file.
Step Completion Reports
After each phase, emit a ◆ block with √/× checks and a Result: PASS | FAIL | PARTIAL line; the format and per-phase checks are in references/edge-cases.md.
Expected Output
The final report for a complete run (full example in references/final-report.md):
Result: COMPLETE — mytool installer
curl -sSL https://raw.githubusercontent.com/owner/mytool/main/install.sh | bash
Evidence:
bash -n install.sh: exit 0; placeholder grep: no matches; shellcheck -S error: exit 0
executor.py --dry-run: "DRY RUN: 5 step(s) listed for mytool; nothing was executed."
Uncertainty:
install.sh was not executed. Raw URL not live until install.sh is pushed to main.
Decision: No approval needed.
Remaining action: commit and push install.sh; delete the three working files.
When a user later runs the one-liner, the script's banner ends:
[INFO] OS: linux | Arch: x86_64 | Package Manager: apt
[ OK ] Dependencies installed
[ OK ] mytool 1.2.0 installed
[ OK ] Installation complete!