Last active
September 25, 2025 13:12
-
-
Save Yeshwanthyk/b0917018840a7f40ae3577b1920dc48c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| usage() { | |
| cat <<'USAGE' | |
| Usage: ai-tools.sh --tool <codex|opencode|gemini> [options] [prompt...] | |
| Options: | |
| -t, --tool <name> Target CLI to invoke (required). | |
| -p, --prompt <text> Add prompt text; can be provided multiple times. | |
| -f, --file <path(s)> Inline file contents; repeatable or comma-separated list. | |
| --model <name> Override default model (currently opencode only). | |
| -h, --help Show this message. | |
| If stdin is provided, it is appended to the prompt as an additional block. | |
| Example: | |
| ai-agent.sh -t opencode -p "Summarize" -f src/main.py | |
| USAGE | |
| } | |
| error() { | |
| echo "Error: $*" >&2 | |
| exit 1 | |
| } | |
| trim() { | |
| local var="$1" | |
| var="${var#${var%%[![:space:]]*}}" | |
| var="${var%${var##*[![:space:]]}}" | |
| printf '%s' "$var" | |
| } | |
| ensure_cmd() { | |
| if ! command -v "$1" >/dev/null 2>&1; then | |
| error "Required command '$1' is not available in PATH." | |
| fi | |
| } | |
| read_env_var() { | |
| local key="$1" | |
| local env_file="${ENV_FILE:-$HOME/.env}" | |
| [[ -f "$env_file" ]] || return 1 | |
| local line value | |
| line=$(grep -E "^(export )?${key}=" "$env_file" | tail -n 1 || true) | |
| [[ -n "$line" ]] || return 1 | |
| value="${line#*=}" | |
| value="${value%\r}" | |
| value="${value%\n}" | |
| value="${value#\"}" | |
| value="${value%\"}" | |
| echo "$value" | |
| } | |
| append_block() { | |
| local content="$1" | |
| [[ -z "$content" ]] && return | |
| if [[ -n "${prompt_payload:-}" ]]; then | |
| prompt_payload+=$'\n\n' | |
| fi | |
| prompt_payload+="$content" | |
| } | |
| prompt_parts=() | |
| files=() | |
| model_override="" | |
| tool="" | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| -t | --tool) | |
| [[ $# -ge 2 ]] || error "--tool requires a value" | |
| tool="$2" | |
| shift 2 | |
| ;; | |
| -p | --prompt) | |
| [[ $# -ge 2 ]] || error "--prompt requires a value" | |
| prompt_parts+=("$2") | |
| shift 2 | |
| ;; | |
| -f | --file) | |
| [[ $# -ge 2 ]] || error "--file requires a path" | |
| IFS=',' read -r -a raw_files <<<"$2" | |
| for entry in "${raw_files[@]}"; do | |
| trimmed=$(trim "$entry") | |
| [[ -z "$trimmed" ]] && continue | |
| if [[ $trimmed == ~* ]]; then | |
| trimmed="${trimmed/#\~/$HOME}" | |
| fi | |
| files+=("$trimmed") | |
| done | |
| shift 2 | |
| ;; | |
| --model) | |
| [[ $# -ge 2 ]] || error "--model requires a value" | |
| model_override="$2" | |
| shift 2 | |
| ;; | |
| -h | --help) | |
| usage | |
| exit 0 | |
| ;; | |
| --) | |
| shift | |
| while [[ $# -gt 0 ]]; do | |
| prompt_parts+=("$1") | |
| shift | |
| done | |
| ;; | |
| *) | |
| prompt_parts+=("$1") | |
| shift | |
| ;; | |
| esac | |
| done | |
| [[ -n "$tool" ]] || error "--tool is required" | |
| tool=$(echo "$tool" | tr '[:upper:]' '[:lower:]') | |
| prompt_payload="" | |
| if [[ ${#prompt_parts[@]} -gt 0 ]]; then | |
| append_block "$(printf '%s' "${prompt_parts[*]}")" | |
| fi | |
| if [[ ! -t 0 ]]; then | |
| stdin_input=$(cat) | |
| append_block "stdin:\n${stdin_input}" | |
| fi | |
| if ((${#files[@]})); then | |
| for file in "${files[@]}"; do | |
| [[ -r "$file" ]] || error "File '$file' not found or not readable" | |
| file_block=$'File: ' | |
| file_block+="$file" | |
| file_block+=$'\n```\n' | |
| file_block+=$(<"$file") | |
| file_block+=$'\n```' | |
| append_block "$file_block" | |
| done | |
| fi | |
| [[ -n "$prompt_payload" ]] || error "Prompt is empty; provide --prompt, positional text, stdin, or --file" | |
| case "$tool" in | |
| codex) | |
| if /bin/zsh -lic 'command -v cdx >/dev/null' >/dev/null 2>&1; then | |
| PROMPT_PAYLOAD="$prompt_payload" exec /bin/zsh -lic 'cdx exec "$PROMPT_PAYLOAD"' | |
| fi | |
| ensure_cmd codex | |
| exec codex exec "$prompt_payload" | |
| ;; | |
| opencode) | |
| ensure_cmd opencode | |
| model_value="${model_override:-openrouter/x-ai/grok-4-fast:free}" | |
| exec opencode run --model "$model_value" "$prompt_payload" | |
| ;; | |
| claude) | |
| ensure_cmd claude | |
| exec claude --dangerously-skip-permissions -p "$prompt_payload" | |
| ;; | |
| gemini) | |
| ensure_cmd gemini | |
| model_value="${model_override:-gemini-2.5-pro}" | |
| exec gemini --model "$model_value" -p "$prompt_payload" | |
| ;; | |
| *) | |
| error "Unsupported tool '$tool'." | |
| ;; | |
| esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment