|
| 1 | +#!/usr/bin/env bash |
| 2 | +# ai_tool_setup.sh |
| 3 | +# Source this file from your ~/.bashrc to enable interactive claude/codex wrapper functions |
| 4 | +# Usage: source /path/to/ai_tool_setup.sh |
| 5 | +# Security: This script sources claude_aliases.sh and codex_aliases.sh which provide the full |
| 6 | +# interactive experience. API keys should be stored in endpoints.conf (see endpoints.conf.example). |
| 7 | + |
| 8 | +# Resolve script directory |
| 9 | +__AI_TOOLBOXX_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" |
| 10 | +CONFIG_FILE="$__AI_TOOLBOXX_DIR/endpoints.conf" |
| 11 | + |
| 12 | +# Export the toolbox directory so alias scripts can use it |
| 13 | +export __AI_TOOLBOXX_DIR |
| 14 | + |
| 15 | +# Load environment variables from .env via load_env.sh if available |
| 16 | +if [ -f "$__AI_TOOLBOXX_DIR/load_env.sh" ]; then |
| 17 | + # shellcheck disable=SC1091 |
| 18 | + . "$__AI_TOOLBOXX_DIR/load_env.sh" >/dev/null 2>&1 || true |
| 19 | +fi |
| 20 | + |
| 21 | +# Helper: list sections in endpoints.conf |
| 22 | +_ai_list_sections() { |
| 23 | + [ -f "$CONFIG_FILE" ] || return 1 |
| 24 | + awk '/^\s*\[/{gsub(/\[|\]/,"",$0); print $0}' "$CONFIG_FILE" |
| 25 | +} |
| 26 | + |
| 27 | +# Helper: get a key value for a section |
| 28 | +_ai_get_value() { |
| 29 | + local section="$1" key="$2" |
| 30 | + [ -f "$CONFIG_FILE" ] || return 1 |
| 31 | + awk -v sec="$section" -v key="$key" ' |
| 32 | + BEGIN{insec=0} |
| 33 | + /^\s*\[/{s=$0; gsub(/\[|\]/,"",s); insec=(s==sec)} |
| 34 | + insec && $0 ~ "^[ \t]*"key"[ \t]*=" { val=substr($0, index($0, "=")+1); gsub(/^[ \t]+|[ \t]+$/,"",val); print val; exit } |
| 35 | + ' "$CONFIG_FILE" |
| 36 | +} |
| 37 | + |
| 38 | +# If the simple awk above fails on some shells, provide a fallback parser |
| 39 | +_ai_get_value_fallback() { |
| 40 | + local section="$1" key="$2" line insec=0 val |
| 41 | + while IFS= read -r line; do |
| 42 | + # trim |
| 43 | + line="${line%%\#*}" |
| 44 | + [[ -z "$line" ]] && continue |
| 45 | + if [[ "$line" =~ ^\s*\[(.+)\]\s*$ ]]; then |
| 46 | + [[ "${BASH_REMATCH[1]}" == "$section" ]] && insec=1 || insec=0 |
| 47 | + continue |
| 48 | + fi |
| 49 | + if [[ $insec -eq 1 && "$line" =~ ^\s*([^=]+)=\s*(.*)\s*$ ]]; then |
| 50 | + k="${BASH_REMATCH[1]// /}" |
| 51 | + v="${BASH_REMATCH[2]}" |
| 52 | + if [[ "$k" == "$key" ]]; then |
| 53 | + printf "%s" "$v" |
| 54 | + return 0 |
| 55 | + fi |
| 56 | + fi |
| 57 | + done < "$CONFIG_FILE" |
| 58 | + return 1 |
| 59 | +} |
| 60 | + |
| 61 | +# Choose parser based on availability |
| 62 | +_ai_get() { |
| 63 | + local val |
| 64 | + val=$(_ai_get_value "$@" 2>/dev/null) || val=$(_ai_get_value_fallback "$@" 2>/dev/null) |
| 65 | + printf "%s" "$val" |
| 66 | +} |
| 67 | + |
| 68 | +# Export helper functions so alias scripts can use them |
| 69 | +export -f _ai_list_sections |
| 70 | +export -f _ai_get_value |
| 71 | +export -f _ai_get_value_fallback |
| 72 | +export -f _ai_get |
| 73 | + |
| 74 | +# Source the claude interactive helper |
| 75 | +if [ -f "$__AI_TOOLBOXX_DIR/claude_aliases.sh" ]; then |
| 76 | + # shellcheck disable=SC1091 |
| 77 | + source "$__AI_TOOLBOXX_DIR/claude_aliases.sh" |
| 78 | +else |
| 79 | + echo "Warning: claude_aliases.sh not found at $__AI_TOOLBOXX_DIR/claude_aliases.sh" >&2 |
| 80 | +fi |
| 81 | + |
| 82 | +# Source the codex interactive helper |
| 83 | +if [ -f "$__AI_TOOLBOXX_DIR/codex_aliases.sh" ]; then |
| 84 | + # shellcheck disable=SC1091 |
| 85 | + source "$__AI_TOOLBOXX_DIR/codex_aliases.sh" |
| 86 | +else |
| 87 | + echo "Warning: codex_aliases.sh not found at $__AI_TOOLBOXX_DIR/codex_aliases.sh" >&2 |
| 88 | +fi |
| 89 | + |
| 90 | +# Source the copilot CLI setup helper |
| 91 | +if [ -f "$__AI_TOOLBOXX_DIR/copilot_cli_setup.sh" ]; then |
| 92 | + # shellcheck disable=SC1091 |
| 93 | + source "$__AI_TOOLBOXX_DIR/copilot_cli_setup.sh" |
| 94 | +else |
| 95 | + echo "Warning: copilot_cli_setup.sh not found at $__AI_TOOLBOXX_DIR/copilot_cli_setup.sh" >&2 |
| 96 | +fi |
| 97 | + |
| 98 | +# Source the gemini CLI setup helper |
| 99 | +if [ -f "$__AI_TOOLBOXX_DIR/gemini_cli_setup.sh" ]; then |
| 100 | + # shellcheck disable=SC1091 |
| 101 | + source "$__AI_TOOLBOXX_DIR/gemini_cli_setup.sh" |
| 102 | +else |
| 103 | + echo "Warning: gemini_cli_setup.sh not found at $__AI_TOOLBOXX_DIR/gemini_cli_setup.sh" >&2 |
| 104 | +fi |
| 105 | + |
| 106 | +# Source the droid CLI setup helper |
| 107 | +if [ -f "$__AI_TOOLBOXX_DIR/droid_cli_setup.sh" ]; then |
| 108 | + # shellcheck disable=SC1091 |
| 109 | + source "$__AI_TOOLBOXX_DIR/droid_cli_setup.sh" |
| 110 | +else |
| 111 | + echo "Warning: droid_cli_setup.sh not found at $__AI_TOOLBOXX_DIR/droid_cli_setup.sh" >&2 |
| 112 | +fi |
| 113 | + |
| 114 | +# If endpoints.conf doesn't exist, create an example copy next to this script |
| 115 | +if [ ! -f "$CONFIG_FILE" ] && [ -f "$__AI_TOOLBOXX_DIR/endpoints.conf.example" ]; then |
| 116 | + cp "$__AI_TOOLBOXX_DIR/endpoints.conf.example" "$CONFIG_FILE" |
| 117 | + echo "Created example config at $CONFIG_FILE. Edit it and replace placeholder api_key values." |
| 118 | +fi |
| 119 | + |
| 120 | +# Prevent direct execution (only allow sourcing) |
| 121 | +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then |
| 122 | + echo "Error: This script must be sourced, not executed." >&2 |
| 123 | + echo "Usage: source ${BASH_SOURCE[0]}" >&2 |
| 124 | + exit 1 |
| 125 | +fi |
| 126 | + |
| 127 | +# Usage instructions |
| 128 | +cat <<USAGE |
| 129 | +
|
| 130 | +✓ AI Toolboxx loaded successfully! |
| 131 | +
|
| 132 | +To enable claude/codex wrappers automatically, add this to your ~/.bashrc: |
| 133 | +
|
| 134 | + source "$__AI_TOOLBOXX_DIR/ai_tool_setup.sh" |
| 135 | +
|
| 136 | +Available commands: |
| 137 | + - claude : Interactive Claude CLI wrapper with model selection |
| 138 | + - codex : Interactive Codex CLI wrapper with model selection |
| 139 | + - copilot : Setup and start GitHub Copilot CLI |
| 140 | + - gemini : Setup and start Google Gemini CLI |
| 141 | + - droid : Setup and start Factory.ai Droid CLI |
| 142 | +
|
| 143 | +Configuration: |
| 144 | + - Edit $CONFIG_FILE to configure endpoints and API keys |
| 145 | + - Use load_env.sh to set per-endpoint API key variables (API_KEY_LITELLM, API_KEY_COPILOT, etc.) |
| 146 | +
|
| 147 | +Security note: |
| 148 | + - API keys should be stored in endpoints.conf or environment variables |
| 149 | + - Do not commit secrets to version control |
| 150 | +
|
| 151 | +USAGE |
0 commit comments