Shifted installers to to tools

This commit is contained in:
2026-06-28 11:21:25 +05:30
parent 5ba08f3d20
commit 6e63e54f1e
27 changed files with 53 additions and 54 deletions

View File

@@ -1,11 +1,11 @@
---
name: add_installer
description: Add a new installer script to the bootstrap CLI project. Use this skill whenever the user asks to create a new installer, add a new tool/package to bootstrap, or register a new `b <name>` command.
name: add_tool
description: Add a new tool definition script to the bootstrap CLI project. Use this skill whenever the user asks to create a new tool, add a new tool/package to bootstrap, or register a new `b <name>` command.
---
# Add a New Installer to Bootstrap CLI
# Add a New Tool to Bootstrap CLI
This skill provides everything needed to add a new installer to the bootstrap project without reading the entire codebase.
This skill provides everything needed to add a new tool to the bootstrap project without reading the entire codebase.
## Project Overview
@@ -15,15 +15,15 @@ Bootstrap CLI (`b`) is a bash-based tool installer and system bootstrapper. User
```
bootstrap/
├── installers/ # Individual installer scripts (install_<name>.sh)
├── lib/ # Shared libraries and router sourced by all installers
├── tools/ # Individual tool directories (tools/<name>/tool.sh)
├── lib/ # Shared libraries and router sourced by all tools
│ ├── common.sh # Logging, confirm(), has_command(), make_temp_dir()
│ ├── platform.sh # detect_distro(), detect_arch(), pkg_install(), pkg_check(), pkg_remove()
│ ├── rollback.sh # Rollback tracking (track_file, track_dir, add_rollback_cmd)
│ ├── shell_config.sh # write_env_snippet, write_alias_snippet, write_completion_snippet
│ ├── registry.sh # Dynamically generated installer registry
│ ├── registry.sh # Dynamically generated tool registry
│ └── routes.sh # Central router script
├── commands/ # Non-installer commands (help, con, uninstall)
├── commands/ # Non-tool commands (help, con, uninstall)
├── assets/ # Assets (logo art, etc.)
│ └── pixel_art.ansi
├── bootstrap.sh # Metascript for environment setup + library loading
@@ -33,12 +33,12 @@ bootstrap/
## Step-by-Step Checklist
When adding a new installer named `<name>`:
When adding a new tool named `<name>`:
### Step 1: Analyze user request & gather details
When the user asks you to create an installer, they often provide either an official `curl` install script or a link to a `.tar.gz` release.
You MUST do the following before writing the script:
When the user asks you to add a tool, they often provide either an official `curl` install script or a link to a `.tar.gz` release.
You MUST do the following before writing the tool script:
If the user provides an official install or curl script in the prompt, or a link to one:
- Execute the `curl` command (or use `read_url_content` or `read_browser_page`) to fetch the script and analyze what it actually does under the hood.
@@ -51,13 +51,15 @@ If the user provides an official install or curl script in the prompt, or a link
**If the user provides a link to a `.tar.gz` (or `.zip`):**
- First, download the archive to a temporary directory and extract it to inspect its contents.
- Analyze the extracted folder structure to decide what needs to be installed (e.g., binaries, man pages, completions) and what should be ignored/deleted.
- Write the `install_<name>` function to download, extract, and copy only those essential files. (Use `download_file` and temporary directories, see "Resumable Download and Extraction" below).
- Write the `install_<name>` function to download, extract, and copy only those essential files. (Use `download_file` and temporary directories, see "GitHub Download and Extraction" below).
### Step 2: Create the installer script
### Step 2: Create the tool script
### Step 3: Add metadata comments to the top of your installer script
Create `tools/<name>/tool.sh` using the template below.
At the top of your new installer script, right below `#!/usr/bin/env bash`, add the following metadata headers:
### Step 3: Add metadata comments to the top of your tool script
At the top of your new tool script, right below `#!/usr/bin/env bash`, add the following metadata headers:
```bash
# Tool: <name>
# DisplayName: <displayName>
@@ -65,7 +67,7 @@ At the top of your new installer script, right below `#!/usr/bin/env bash`, add
# Strategy: <strategy> (binary | managed | system)
```
The central router `lib/routes.sh` and autocomplete function in `b.sh` will dynamically parse this metadata from all `install_*.sh` scripts to register the installer and keys automatically! No manual edits to `lib/routes.sh` or `b.sh` are required.
The central router `lib/routes.sh` and autocomplete function in `b.sh` will dynamically parse this metadata from all `tools/*/tool.sh` scripts to register the tool and keys automatically! No manual edits to `lib/routes.sh` or `b.sh` are required.
### Step 4: Implement Rollback Tracking (Crucial)
@@ -78,16 +80,16 @@ To ensure the user can seamlessly use `b rb <name>` to uninstall or rollback a t
### Step 5: Verify (optional)
Verify that the installer works and appears in the help output:
Verify that the tool works and appears in the help output:
- Run `b all` to confirm it appears in the help list.
- Run `b ware <name> -y` to test direct installation.
- Run `b ware <name>` to test the interactive editing flow.
---
## Installer Script Template
## Tool Script Template
Every installer follows this exact structure. Copy this and fill in the tool-specific logic (notice there are no standalone execution guards or curl checks):
Every tool follows this exact structure. Copy this and fill in the tool-specific logic (notice there are no standalone execution guards or curl checks):
```bash
#!/usr/bin/env bash
@@ -152,7 +154,7 @@ main "$@"
## Available Library Functions
These are pre-loaded by `bootstrap.sh` — no need to source them manually in installers.
These are pre-loaded by `bootstrap.sh` — no need to source them manually in tool scripts.
### From `lib/common.sh`
@@ -248,7 +250,7 @@ track_file "$BOOTSTRAP_BIN/binary"
## Rules & Conventions
1. **File naming**: Always `install_<name>.sh` in the `installers/` directory.
1. **File naming**: Always `tools/<name>/tool.sh`.
2. **Confirmation prompts**: Always ask before installing. Check if already installed first.
3. **Rollback Tracking**: NEVER omit rollback hooks. If you move a file to `$BOOTSTRAP_BIN`, you MUST call `track_file`. If you build/install manually (e.g. via `makepkg -si`), you MUST call `add_rollback_cmd "sudo pacman -R --noconfirm <pkg>"` or equivalent.
4. **Shell Drop-ins**: Always use `write_env_snippet`, `write_alias_snippet`, or `write_completion_snippet` instead of manually injecting code directly into `~/.bashrc`.

View File

@@ -20,11 +20,11 @@ When the user asks to "cut a release", "bump the version", or "tag a new version
git log $(git describe --tags --abbrev=0)..HEAD --oneline
```
2. **Determine the bump level** using semantic versioning rules:
- Skip any commits that only touch `installers/` or docs — those don't warrant a bump.
- Skip any commits that only touch `tools/` or docs — those don't warrant a bump.
- If any commit has `BREAKING CHANGE` or `!:` → **major**
- If any core-CLI commit has `feat:` → **minor**
- Otherwise (only `fix:`, `refactor:`, etc. in core-CLI) → **patch**
- If *all* commits are installer-only or docs-only → inform the user no release is needed.
- If *all* commits are tool-only or docs-only → inform the user no release is needed.
3. **Formulate a verbose, structured description of the changes** based on the analyzed commits. Group the changes into logical sections (such as "Breaking Changes & Major Features:" and "Other Updates:") and list the corresponding commit messages or summaries. Example format:
```text
Breaking Changes & Major Features:

8
b.sh
View File

@@ -93,8 +93,8 @@ _b_completion() {
local routes_dir="$HOME/.config/bootstrap"
local installer_keys=""
if [ -d "$routes_dir/installers" ]; then
for f in "$routes_dir/installers"/install_*.sh; do
if [ -d "$routes_dir/tools" ]; then
for f in "$routes_dir/tools"/*/tool.sh; do
if [ -f "$f" ]; then
local tool
tool=$(grep -E "^# Tool:" "$f" | head -n1 | sed -E 's/^# Tool:\s*//I')
@@ -135,8 +135,8 @@ _b_completion() {
if [ "$COMP_CWORD" -eq 2 ] && { [ "$prev" = "ware" ] || [ "$prev" = "bware" ]; }; then
local routes_dir="$HOME/.config/bootstrap"
local installer_keys=""
if [ -d "$routes_dir/installers" ]; then
for f in "$routes_dir/installers"/install_*.sh; do
if [ -d "$routes_dir/tools" ]; then
for f in "$routes_dir/tools"/*/tool.sh; do
if [ -f "$f" ]; then
local tool
tool=$(grep -E "^# Tool:" "$f" | head -n1 | sed -E 's/^# Tool:\s*//I')

View File

@@ -120,10 +120,10 @@ EOF
fi
done
# Also copy installers if they exist locally
if [ -d "$_SCRIPT_DIR/installers" ]; then
mkdir -p "$routes_dir/installers"
cp -r "$_SCRIPT_DIR/installers/"* "$routes_dir/installers/"
# Also copy tools if they exist locally
if [ -d "$_SCRIPT_DIR/tools" ]; then
mkdir -p "$routes_dir/tools"
cp -r "$_SCRIPT_DIR/tools/"* "$routes_dir/tools/"
fi
# Also copy plugins if they exist locally

View File

@@ -1,13 +1,13 @@
# shellcheck shell=bash
# Command: help
# Lists all available bootstrap commands and installers
# Lists all available bootstrap commands and tools
echo "Available bootstrap commands:"
# Non-installers first (aligned to 6 chars width)
# Non-tools first (aligned to 6 chars width)
printf " %-6s - %s\n" "all" "List all available commands"
printf " %-6s - %s\n" "con" "Edit config (e.g. b con nvim)"
printf " %-6s - %s\n" "up" "Check for updates and update Bootstrap CLI"
printf " %-6s - %s\n" "ware" "Edit and run an installer (e.g. b ware nvim)"
printf " %-6s - %s\n" "ware" "Edit and run a tool (e.g. b ware nvim)"
printf " %-6s - %s\n" "gone" "Uninstall Bootstrap CLI helper"

View File

@@ -1,6 +1,6 @@
# Plugin Development Guide
Plugins are first-party or third-party applications written to work directly with `bootstrap`. Unlike installers (or packages) which modify your system by compiling code, downloading binaries, and altering shell configuration files, **plugins are lazy-loaded scripts that execute within a sandboxed subshell**.
Plugins are first-party or third-party applications written to work directly with `bootstrap`. Unlike tools (or packages) which modify your system by compiling code, downloading binaries, and altering shell configuration files, **plugins are lazy-loaded scripts that execute within a sandboxed subshell**.
This means downloading and invoking a plugin makes no system modifications other than caching the `.sh` file itself. They are fetched only the very first time you invoke them.

View File

@@ -52,7 +52,7 @@ If the argument does not match an installed tool in the registry, it is treated
## 4. Required Abstractions & Helper Modifications
### A. Context Initialization
Before executing an installer script, the `b` CLI initializes the command list:
Before executing a tool script, the `b` CLI initializes the command list:
```bash
export BOOTSTRAP_UNINSTALLER_CMDS="$HOME/.local/state/bootstrap/uninstallers/nvim.cmds"
mkdir -p "$(dirname "$BOOTSTRAP_UNINSTALLER_CMDS")"
@@ -97,7 +97,7 @@ log_success "Rollback complete."
```
## 6. Resilience Against User Modifications
Because `b ware <tool>` allows users to modify installation scripts:
Because `b ware <tool>` allows users to modify tool scripts:
1. **Dynamic Adaptation:** The manifest is built *during* execution, adapting to whatever packages the user manually added.
2. **Fault Isolation:** The `eval` loop ensures that a syntax error in one custom rollback step doesn't crash the removal of other tracked packages.
@@ -113,7 +113,7 @@ When a tool is uninstalled:
To handle failures during installation (e.g., network drops, script errors, or user cancellation via `Ctrl+C`), the CLI incorporates a transactional approach that balances **automatic rollback** and **resumability**:
### A. The Interruption Trap & Prompt
When running an installer, the central router (`lib/routes.sh`) traps `SIGINT` and `SIGTERM` signals. If the installation fails or is interrupted:
When running a tool, the central router (`lib/routes.sh`) traps `SIGINT` and `SIGTERM` signals. If the installation fails or is interrupted:
1. The trap catches the event and stops execution.
2. The user is prompted interactively:
- **Rollback (r)**: Invokes `execute_rollback <tool>` immediately to clean up all partial modifications.
@@ -130,6 +130,6 @@ If the user chooses to **keep** the partial state and runs `b <tool>` again:
To make rerunning an interrupted script fast and efficient, installers use `download_file <url> <dest>` instead of raw `curl`:
1. It downloads the payload to a central cache directory: `~/.local/state/bootstrap/cache/`.
2. It uses `curl -C -` to continue the download from the byte offset where it was interrupted.
3. Once completed, it copies the cached file to the installer's temp directory.
3. Once completed, it copies the cached file to the tool's temp directory.
4. Distro package manager commands (`pkg_install`) and shell snippets (`write_env_snippet`) are naturally idempotent, allowing the script to breeze through already completed steps in milliseconds and resume exactly where the heavy work failed.

View File

@@ -6,7 +6,7 @@ The Bootstrap CLI uses a semantic, git-tag-driven versioning workflow.
- **Do not manually edit the `VERSION` file.**
- Develop normally using [Conventional Commits](https://www.conventionalcommits.org/) (e.g., `feat: Add new tool`, `fix: Typo in script`).
- **Note on Installers:** Adding or modifying installers in the `installers/` directory **does not** require a version bump. They are fetched dynamically from the registry when a user runs `b ware <tool>`.
- **Note on Tools:** Adding or modifying tools in the `tools/` directory **does not** require a version bump. They are fetched dynamically from the registry when a user runs `b ware <tool>`.
## 2. When to Cut a Release

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# GitHub API helper functions for Bootstrap installers
# GitHub API helper functions for Bootstrap tools
# Usage: github_get_latest_release <owner/repo>
# Prints the tag_name of the latest release.

View File

@@ -7,7 +7,6 @@ declare -A INSTALLERS=(
[asciicinema]="asciinema terminal recorder"
[bat]="Bat (alternative to cat) and configure alias"
[docker]="Container runtime and orchestration platform"
[hyperfine]="Command-line benchmarking tool"
[lazygit]="Simple terminal UI for git commands"
[node]="Node.js (LTS) and NVM"
[nvim]="Neovim 0.12.0 and configuration"
@@ -25,7 +24,6 @@ declare -A INSTALLER_DISPLAYS=(
[asciicinema]="asciicinema"
[bat]="Bat"
[docker]="Docker"
[hyperfine]="Hyperfine"
[lazygit]="lazygit"
[node]="Node"
[nvim]="Neovim"
@@ -43,7 +41,6 @@ declare -A INSTALLER_STRATEGIES=(
[asciicinema]="binary"
[bat]="binary"
[docker]="system"
[hyperfine]="binary"
[lazygit]="binary"
[node]="managed"
[nvim]="binary"
@@ -56,4 +53,4 @@ declare -A INSTALLER_STRATEGIES=(
[zoxide]="managed"
)
INSTALLER_KEYS=(agy asciicinema bat docker hyperfine lazygit node nvim pnpm rust starship uv yay yazi zoxide)
INSTALLER_KEYS=(agy asciicinema bat docker lazygit node nvim pnpm rust starship uv yay yazi zoxide)

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Central routing script for bootstrap installers.
# Central routing script for bootstrap tools.
# This file is updated automatically by the 'b' command.
_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd 2>/dev/null || pwd)"
@@ -69,8 +69,8 @@ run_ware() {
display_name="$(echo "${tool:0:1}" | tr '[:lower:]' '[:upper:]')${tool:1}"
fi
# Check for local installer first
local local_installer="$BOOTSTRAP_DIR/installers/install_${tool}.sh"
# Check for local tool definition first
local local_installer="$BOOTSTRAP_DIR/tools/${tool}/tool.sh"
if [ "$bypass_edit" = "true" ] && [ -f "$local_installer" ]; then
log_info "Running ${display_name} installer..."
@@ -86,7 +86,7 @@ run_ware() {
else
BOOTSTRAP_BASE_URL="${BOOTSTRAP_BASE_URL:-https://git.adityagupta.dev/sortedcord/bootstrap/raw/branch/master}"
BOOTSTRAP_FALLBACK_URL="${BOOTSTRAP_FALLBACK_URL:-https://raw.githubusercontent.com/sortedcord/bootstrap/refs/heads/master}"
local installer_path="installers/install_${tool}.sh"
local installer_path="tools/${tool}/tool.sh"
local download_status=0
log_info "Downloading ${display_name} installer..."

View File

@@ -145,7 +145,7 @@ This retrieves the pending device's public key, prompts the administrator for co
## Plugins (`b <plugin_name>`)
Plugins are first-party or third-party applications written to work directly with `bootstrap`. Unlike installers (or packages) which modify your system by compiling code, downloading binaries, and altering shell configuration files, **plugins are lazy-loaded scripts that execute within a subshell**.
Plugins are first-party or third-party applications written to work directly with `bootstrap`. Unlike tools (or packages) which modify your system by compiling code, downloading binaries, and altering shell configuration files, **plugins are lazy-loaded scripts that execute within a subshell**.
Downloading and invoking a plugin makes no system modifications other than caching the `.sh` file itself. They are fetched only the very first time you invoke them.
@@ -263,8 +263,8 @@ Running scripts directly from the internet is convenient but should always be ap
### Why Bootstrap is More Secure
Instead of blindly piping large, third-party installation scripts (often hundreds or thousands of lines of unscrutinized code) directly from the internet into your shell, Bootstrap uses a **scrutinized and simplified** approach:
1. **Audited & Minimised**: Every script in `installers/` has been scrutinized, refactored, and stripped of redundant compatibility layers (like Windows/macOS support or complex environment checks), leaving only the essential, readable logic required for your setup.
2. **Controlled Execution**: Since installer scripts are hosted locally in your cloned repository, you can review every line of code before executing it. You are never subject to silent, upstream changes to installers.
1. **Audited & Minimised**: Every script in `tools/` has been scrutinized, refactored, and stripped of redundant compatibility layers (like Windows/macOS support or complex environment checks), leaving only the essential, readable logic required for your setup.
2. **Controlled Execution**: Since tool scripts are hosted locally in your cloned repository, you can review every line of code before executing it. You are never subject to silent, upstream changes to tools.
3. **No Raw Pipes**: We download official binary releases directly to verified temporary locations rather than running arbitrary third-party script pipelines.
If you want to audit the core Bootstrap CLI itself before running it:

View File

@@ -5,7 +5,7 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$(dirname "$SCRIPT_DIR")"
INSTALLERS_DIR="$REPO_DIR/installers"
TOOLS_DIR="$REPO_DIR/tools"
REGISTRY_FILE="$REPO_DIR/lib/registry.sh"
echo "==> Generating registry.sh..."
@@ -16,7 +16,7 @@ declare -A tools_disp
declare -A tools_strat
keys=()
for f in "$INSTALLERS_DIR"/install_*.sh; do
for f in "$TOOLS_DIR"/*/tool.sh; do
[ -f "$f" ] || continue
tool=$(grep -E "^# Tool:" "$f" | head -n1 | sed -E 's/^# Tool:\s*//I')
disp_name=$(grep -E "^# DisplayName:" "$f" | head -n1 | sed -E 's/^# DisplayName:\s*//I')