diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-13 23:21:32 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-13 23:21:32 -0500 |
| commit | 3eed2e185773451574c51a4bad591a2753dac662 (patch) | |
| tree | 571c83e0089484962f2e941801787710d5c9c0d8 /claude-templates/bin | |
| parent | 1b98a9ed2acff1605895700302ff276ba88baa5b (diff) | |
| download | rulesets-3eed2e185773451574c51a4bad591a2753dac662.tar.gz rulesets-3eed2e185773451574c51a4bad591a2753dac662.zip | |
feat(launcher): bare ai picks the agent before the projects
The interactive flow now opens with a runtime picker: claude first (Enter-Enter preserves the old two-keystroke habit), codex labeled as ChatGPT, and one local:<model> line per ollama model, queried live with a short timeout so a dead server just drops those lines. The pick feeds the existing runtime map, then the annotated project multi-select runs as before. --runtime and AI_RUNTIME skip the question, single-directory mode is unchanged, and --print-runtimes exposes the choice list for the two new bats tests.
Diffstat (limited to 'claude-templates/bin')
| -rwxr-xr-x | claude-templates/bin/ai | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/claude-templates/bin/ai b/claude-templates/bin/ai index c805e8b..cf17875 100755 --- a/claude-templates/bin/ai +++ b/claude-templates/bin/ai @@ -2,10 +2,12 @@ # ai — agent session launcher (unified aix + hey) # # Usage: -# ai Select one or more projects via fzf and open each in -# an 'ai' tmux session window (creates session if needed). +# ai Pick the agent first (claude, codex/ChatGPT, or any +# local ollama model), then select one or more projects +# via fzf; each opens in an 'ai' tmux session window. # Git-aware: fetches, annotates with ↑/↓/dirty, auto-pulls -# clean-and-behind repos before opening. +# clean-and-behind repos before opening. --runtime or +# AI_RUNTIME skips the agent pick. # # ai <dir>... Single-project mode. Opens each given directory directly # in the 'ai' session (new window or switch to existing). @@ -51,6 +53,36 @@ resolve_agent_cmd() { esac } +# One line per launchable agent, claude first (Enter-Enter keeps the old +# muscle memory). Local models appear only when both codex (the CLI that +# drives them) and a live ollama answer; a dead server just drops the lines. +build_runtime_choices() { + command -v claude >/dev/null 2>&1 && echo "claude — Claude Code" + command -v codex >/dev/null 2>&1 && echo "codex — ChatGPT (Codex CLI)" + if command -v codex >/dev/null 2>&1 && command -v ollama >/dev/null 2>&1; then + timeout 3 ollama list 2>/dev/null | tail -n +2 | awk 'NF {print "local:" $1 " — ollama"}' + fi +} + +# Interactive runtime pick for the bare-`ai` flow. Sets RUNTIME (and +# LOCAL_MODEL for a local pick) and re-resolves the agent command. +# Returns 1 when the pick is cancelled. +pick_runtime() { + local choice + choice=$(build_runtime_choices | fzf --height=30% --reverse --prompt='agent> ') || return 1 + [ -z "$choice" ] && return 1 + case "$choice" in + claude*) RUNTIME="claude" ;; + codex*) RUNTIME="codex" ;; + local:*) + RUNTIME="local" + LOCAL_MODEL="${choice#local:}" + LOCAL_MODEL="${LOCAL_MODEL%% *}" + ;; + esac + resolve_agent_cmd +} + # Run in the pane's shell just before Claude launches. `stty susp undef` clears # the tty's SIGTSTP (C-z) character for this pane only, so an accidental C-z is # passed through to Claude as input rather than suspending the session to the @@ -70,7 +102,7 @@ build_instructions() { } usage() { - sed -n '2,20p' "$0" | sed 's|^# \?||' + sed -n '2,23p' "$0" | sed 's|^# \?||' exit 0 } @@ -447,24 +479,31 @@ print_launch_mode() { # ---------- dispatch ---------- print_launch="" +runtime_explicit="${AI_RUNTIME:+1}" while [ $# -gt 0 ]; do case "$1" in -h|--help) usage ;; --runtime) - [ -z "${2:-}" ] && { echo "ai: --runtime needs a value — valid runtimes: claude, codex" >&2; exit 2; } + [ -z "${2:-}" ] && { echo "ai: --runtime needs a value — valid runtimes: claude, codex, local" >&2; exit 2; } RUNTIME="$2" + runtime_explicit=1 shift 2 ;; --runtime=*) RUNTIME="${1#--runtime=}" + runtime_explicit=1 shift ;; --print-launch) print_launch=1 shift ;; + --print-runtimes) + build_runtime_choices + exit 0 + ;; *) break ;; @@ -478,16 +517,22 @@ if [ -n "$print_launch" ]; then print_launch_mode "$1" fi -check_deps - case "${1:-}" in --attach) + check_deps attach_mode ;; "") + # Bare `ai`: pick the agent first (skipped when --runtime or AI_RUNTIME + # already chose), then the familiar project multi-select. + if [ -z "$runtime_explicit" ]; then + pick_runtime || exit 0 + fi + check_deps multi_mode ;; *) + check_deps for arg in "$@"; do single_mode "$arg" done |
