diff --git a/.agents/skills/add_installer/SKILL.md b/.agents/skills/add_installer/SKILL.md index b7c2cc0..b20fb42 100644 --- a/.agents/skills/add_installer/SKILL.md +++ b/.agents/skills/add_installer/SKILL.md @@ -20,7 +20,7 @@ bootstrap/ │ ├── 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 +│ ├── shell_config.sh # write_env_snippet, write_alias_snippet, write_completion_snippet │ ├── registry.sh # Dynamically generated installer registry │ └── routes.sh # Central router script ├── commands/ # Non-installer commands (help, con, uninstall) @@ -62,7 +62,7 @@ To ensure the user can seamlessly use `b rb `, all manual modifications mu - When extracting binaries to `~/.local/bin/`, use `track_file "$HOME/.local/bin/binary"`. - When creating directories like `~/.config/tool/`, use `track_dir "$HOME/.config/tool"`. - When running manual apt/dnf/npm commands, log their inverses: `add_rollback_cmd "sudo npm uninstall -g package"`. -Note: `pkg_install`, `write_env_snippet`, and `write_alias_snippet` will automatically track themselves. +Note: `pkg_install`, `write_env_snippet`, `write_alias_snippet`, and `write_completion_snippet` will automatically track themselves. ### Step 4: Verify (optional) @@ -126,6 +126,7 @@ configure_shell() { # Use drop-in snippets for shell configuration (they auto-rollback) # write_env_snippet "" "export VAR_NAME=value\neval \"\$( init bash)\"" # write_alias_snippet "" "alias =''" + # write_completion_snippet "" "source <( completion bash)" : } @@ -184,6 +185,7 @@ These are pre-loaded by `bootstrap.sh` — no need to source them manually in in |---|---| | `write_env_snippet ` | Creates an isolated `env.d/` shell drop-in snippet and registers it for rollback. | | `write_alias_snippet ` | Creates an isolated `aliases.d/` shell drop-in snippet and registers it for rollback. | +| `write_completion_snippet ` | Creates an isolated `completions.d/` bash completion snippet and registers it for rollback. | --- @@ -241,7 +243,7 @@ track_file "/usr/local/bin/binary" 1. **File naming**: Always `install_.sh` in the `installers/` directory. 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 `~/.local/bin/`, you MUST call `track_file`. If you run `makepkg`, you MUST call `add_rollback_cmd` for `pacman -R`. -4. **Shell Drop-ins**: Always use `write_env_snippet` or `write_alias_snippet` instead of manually injecting code directly into `~/.bashrc`. +4. **Shell Drop-ins**: Always use `write_env_snippet`, `write_alias_snippet`, or `write_completion_snippet` instead of manually injecting code directly into `~/.bashrc`. 5. **No hardcoded paths**: Use `$HOME`, library functions, and `detect_*` helpers. 6. **Error handling**: Use `set -euo pipefail` after the guard block. 7. **CLI Enforcement Guard**: Always copy the standalone execution guard block verbatim to the top of your installer script to prevent direct execution. diff --git a/bootstrap.sh b/bootstrap.sh index 8aac6c8..64a1cbc 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -71,6 +71,7 @@ install_bootstrap() { mkdir -p "$routes_dir" mkdir -p "$routes_dir/env.d" mkdir -p "$routes_dir/aliases.d" + mkdir -p "$routes_dir/completions.d" # List of all files to download/copy local files=( @@ -142,6 +143,7 @@ export BOOTSTRAP_DIR="$HOME/.config/bootstrap" [ -f "$BOOTSTRAP_DIR/b.sh" ] && . "$BOOTSTRAP_DIR/b.sh" for f in "$BOOTSTRAP_DIR/env.d/"*.sh; do [ -r "$f" ] && . "$f"; done for f in "$BOOTSTRAP_DIR/aliases.d/"*.sh; do [ -r "$f" ] && . "$f"; done +for f in "$BOOTSTRAP_DIR/completions.d/"*.sh; do [ -r "$f" ] && . "$f"; done # <<< bootstrap-cli setup <<< EOF diff --git a/lib/shell_config.sh b/lib/shell_config.sh index acf6632..afe72be 100644 --- a/lib/shell_config.sh +++ b/lib/shell_config.sh @@ -158,6 +158,34 @@ remove_alias_snippet() { fi } +# Write completion snippet to completions.d/ +# Usage: write_completion_snippet +write_completion_snippet() { + local name="$1" + local content="$2" + local dir="${BOOTSTRAP_DIR:-$HOME/.config/bootstrap}/completions.d" + + mkdir -p "$dir" + log_info "Writing completion snippet '$name' to $dir/${name}.sh" + echo "$content" > "$dir/${name}.sh" + + if type add_rollback_cmd >/dev/null 2>&1; then + add_rollback_cmd "rm -f \"$dir/${name}.sh\"" + fi +} + +# Remove completion snippet from completions.d/ +# Usage: remove_completion_snippet +remove_completion_snippet() { + local name="$1" + local dir="${BOOTSTRAP_DIR:-$HOME/.config/bootstrap}/completions.d" + + if [ -f "$dir/${name}.sh" ]; then + log_info "Removing completion snippet '$name'" + rm -f "$dir/${name}.sh" + fi +} + # Setup fd symlink for Debian/Ubuntu (fdfind -> fd) create_fd_symlink() { if ! has_command fd && has_command fdfind; then @@ -176,8 +204,4 @@ source_bashrc() { # Export functions and variables for subshells export _LIB_SHELL_CONFIG_SOURCED=1 -export -f get_shell_configs remove_block inject_block add_alias_if_missing add_env_if_missing create_fd_symlink write_env_snippet write_alias_snippet remove_env_snippet remove_alias_snippet source_bashrc - - - - +export -f get_shell_configs remove_block inject_block add_alias_if_missing add_env_if_missing create_fd_symlink write_env_snippet write_alias_snippet remove_env_snippet remove_alias_snippet write_completion_snippet remove_completion_snippet source_bashrc