mirror of
https://github.com/msitarzewski/agency-agents/
synced 2026-06-09 10:13:17 +00:00
feat(installer): consistent screen layout across all 3 screens
Standard vertical rhythm everywhere: pager -> description -> content -> selection summary -> navigation -> warnings. Splits the selector footer into separate summary/nav/warning lines (SEL_SUMMARY_FN/SEL_NAV/ SEL_WARN_FN) and reorders the Review screen to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+37
-23
@@ -426,7 +426,7 @@ division_emoji() {
|
||||
}
|
||||
|
||||
# Generic multi-select. Inputs (globals): OPT_LABEL[], OPT_SEL[];
|
||||
# SEL_TITLE, SEL_HINT, SEL_FOOTER_FN (name of fn echoing a footer line).
|
||||
# SEL_TITLE, SEL_HINT, SEL_SUMMARY_FN, SEL_NAV, SEL_WARN_FN.
|
||||
# Mutates OPT_SEL[]; sets SEL_RESULT = next|back|quit.
|
||||
selector() {
|
||||
local n=${#OPT_LABEL[@]} cur=0 top=0 query="" searching=false key i idx vn rows W
|
||||
@@ -456,7 +456,10 @@ selector() {
|
||||
buf+=" $cg [$mark] $label"$'\n'
|
||||
done
|
||||
local shown=$(( vn<rows ? vn : rows )); for (( i=shown; i<rows; i++ )); do buf+=$'\n'; done
|
||||
buf+=$'\n'" ${C_DIM}$("$SEL_FOOTER_FN")${C_RESET}"$'\n'
|
||||
# Consistent footer: summary -> nav -> warnings (-> search line)
|
||||
buf+=$'\n'" ${C_BOLD}$("$SEL_SUMMARY_FN")${C_RESET}"$'\n'
|
||||
buf+=" ${C_DIM}${SEL_NAV}${C_RESET}"$'\n'
|
||||
local _w; _w="$("$SEL_WARN_FN")"; [[ -n "$_w" ]] && buf+=" ${C_YELLOW}${_w}${C_RESET}"$'\n'
|
||||
if $searching; then buf+=" ${C_CYAN}search:${C_RESET} ${query}_"$'\n'
|
||||
elif [[ -n "$query" ]]; then buf+=" ${C_CYAN}/${query}${C_RESET} ${C_DIM}(esc clears)${C_RESET}"$'\n'; fi
|
||||
draw_frame "$buf"
|
||||
@@ -488,9 +491,10 @@ selector() {
|
||||
}
|
||||
|
||||
# --- Screen: Tools ---
|
||||
_tools_footer() {
|
||||
_no_warn() { :; }
|
||||
_tools_summary() {
|
||||
local i c=0; for (( i=0; i<${#OPT_SEL[@]}; i++ )); do [[ "${OPT_SEL[$i]}" == 1 ]] && c=$(( c+1 )); done
|
||||
printf '%s tools selected · space toggle · a all · d detected · / search · enter next · q quit' "$c"
|
||||
printf '%s of %s tools selected' "$c" "${#OPT_SEL[@]}"
|
||||
}
|
||||
screen_tools() {
|
||||
OPT_LABEL=(); OPT_SEL=()
|
||||
@@ -502,11 +506,11 @@ screen_tools() {
|
||||
label="$(printf '%s %-13s %s' "$det" "$(tool_simple_name "$t")" "${C_DIM}${path:-not found}${C_RESET}")"
|
||||
OPT_LABEL+=("$label"); OPT_SEL+=("${TOOL_SEL[$i]:-0}")
|
||||
done
|
||||
SEL_TITLE="The Agency · Installer — 1/3 Tools"
|
||||
SEL_HINT="Pick where to install."
|
||||
SEL_FOOTER_FN=_tools_footer
|
||||
# extra key: 'd' selects detected — handle by pre/post; selector lacks it, so
|
||||
# we add it via a tiny wrapper below.
|
||||
SEL_TITLE="The Agency · Installer — 1/3 · Tools"
|
||||
SEL_HINT="Pick where to install. ${GLYPH_DET} = detected on this machine."
|
||||
SEL_SUMMARY_FN=_tools_summary
|
||||
SEL_NAV="space toggle · a all · n none · / search · enter next · q quit"
|
||||
SEL_WARN_FN=_no_warn
|
||||
selector
|
||||
for (( i=0; i<${#OPT_SEL[@]}; i++ )); do TOOL_SEL[$i]="${OPT_SEL[$i]}"; done
|
||||
}
|
||||
@@ -528,15 +532,16 @@ _teams_agents() {
|
||||
done
|
||||
echo "$c"
|
||||
}
|
||||
_teams_footer() {
|
||||
_teams_summary() {
|
||||
local sel=0 i a; a="$(_teams_agents)"
|
||||
for (( i=0; i<${#OPT_SEL[@]}; i++ )); do [[ "${OPT_SEL[$i]}" == 1 ]] && sel=$(( sel+1 )); done
|
||||
local note=""
|
||||
local cap; cap="$(tool_cap opencode)"
|
||||
printf '%s agents · %s of %s teams' "$a" "$sel" "${#OPT_SEL[@]}"
|
||||
}
|
||||
_teams_warn() {
|
||||
local a cap; a="$(_teams_agents)"; cap="$(tool_cap opencode)"
|
||||
if _opencode_selected && [[ "$a" -gt "$cap" ]]; then
|
||||
note=" ${C_YELLOW}⚠ OpenCode caps ~${cap}${C_RESET}"
|
||||
printf "⚠ OpenCode registers ~%s; ~%s of %s won't load (#27988)" "$cap" "$(( a - cap ))" "$a"
|
||||
fi
|
||||
printf '%s agents · %s/%s teams%s · space · a all · n none · / search · enter next · ← back' "$a" "$sel" "${#ALL_DIVISIONS[@]}" "$note"
|
||||
}
|
||||
_opencode_selected() {
|
||||
local i; for (( i=0; i<${#TOOL_SEL[@]}; i++ )); do
|
||||
@@ -551,9 +556,11 @@ screen_teams() {
|
||||
OPT_LABEL+=("$(printf '%s %-20s %s' "$(division_emoji "$d")" "$d" "${C_DIM}${TEAM_COUNTS[$i]} agents${C_RESET}")")
|
||||
OPT_SEL+=("${TEAM_SEL[$i]:-1}")
|
||||
done
|
||||
SEL_TITLE="The Agency · Installer — 2/3 Teams"
|
||||
SEL_TITLE="The Agency · Installer — 2/3 · Teams"
|
||||
SEL_HINT="Pick which teams to install. Fewer teams keeps OpenCode under its limit."
|
||||
SEL_FOOTER_FN=_teams_footer
|
||||
SEL_SUMMARY_FN=_teams_summary
|
||||
SEL_NAV="space toggle · a all · n none · / search · enter next · ← back · q quit"
|
||||
SEL_WARN_FN=_teams_warn
|
||||
selector
|
||||
for (( i=0; i<${#OPT_SEL[@]}; i++ )); do TEAM_SEL[$i]="${OPT_SEL[$i]}"; done
|
||||
}
|
||||
@@ -585,22 +592,29 @@ screen_review() {
|
||||
agents=0; for (( i=0; i<${#TEAM_SEL[@]}; i++ )); do [[ "${TEAM_SEL[$i]}" == 1 ]] && agents=$(( agents + ${TEAM_COUNTS[$i]} )); done
|
||||
local cur=0 # 0=Install 1=mode toggle
|
||||
while true; do
|
||||
local buf="" W=66
|
||||
buf+=" ${C_BOLD}${C_CYAN}${BX_TL}${BX_H}${BX_H} Review — 3/3 $(repeat "$BX_H" 46)${BX_TR}${C_RESET}"$'\n\n'
|
||||
buf+=" ${C_BOLD}Installing ${agents} agents${C_RESET} from ${#teams[@]} teams to ${#tools[@]} tools"$'\n\n'
|
||||
local buf="" m
|
||||
# pager
|
||||
buf+=" ${C_BOLD}${C_CYAN}${BX_TL}${BX_H}${BX_H} The Agency · Installer — 3/3 · Review $(repeat "$BX_H" 28)${BX_TR}${C_RESET}"$'\n'
|
||||
# description
|
||||
buf+=" ${C_DIM}Confirm your selection, then install.${C_RESET}"$'\n\n'
|
||||
# content: the selections + the mode toggle
|
||||
buf+=" ${C_BOLD}Tools${C_RESET} ${C_DIM}(${#tools[@]})${C_RESET}"$'\n'
|
||||
buf+="$(grid_2col 16 ${tools[@]+"${tools[@]}"})"$'\n'
|
||||
buf+=" ${C_BOLD}Teams${C_RESET} ${C_DIM}(${#teams[@]})${C_RESET}"$'\n'
|
||||
buf+="$(grid_2col 20 ${teams[@]+"${teams[@]}"})"$'\n\n'
|
||||
local m; $USE_LINK && m="symlink" || m="copy"
|
||||
$USE_LINK && m="symlink" || m="copy"
|
||||
if (( cur==1 )); then buf+=" ${C_CYAN}${GLYPH_CUR}${C_RESET} Mode: ${C_BOLD}${m}${C_RESET} ${C_DIM}(space toggles copy/symlink)${C_RESET}"$'\n'
|
||||
else buf+=" Mode: ${m} ${C_DIM}(space toggles copy/symlink)${C_RESET}"$'\n'; fi
|
||||
buf+=$'\n'
|
||||
if (( cur==0 )); then buf+=" ${C_CYAN}${GLYPH_CUR}${C_RESET} ${C_BOLD}${C_GREEN}Install${C_RESET} ← back q quit"$'\n'
|
||||
else buf+=" ${C_GREEN}Install${C_RESET} ← back q quit"$'\n'; fi
|
||||
# summary
|
||||
buf+=" ${C_BOLD}Installing ${agents} agents · ${#teams[@]} teams · ${#tools[@]} tools${C_RESET}"$'\n'
|
||||
# navigation (Install is the action cursor target)
|
||||
if (( cur==0 )); then buf+=" ${C_CYAN}${GLYPH_CUR}${C_RESET} ${C_BOLD}${C_GREEN}Install${C_RESET} ${C_DIM}↑/↓ move · enter install · ← back · q quit${C_RESET}"$'\n'
|
||||
else buf+=" ${C_GREEN}Install${C_RESET} ${C_DIM}↑/↓ move · space toggle mode · ← back · q quit${C_RESET}"$'\n'; fi
|
||||
# warnings
|
||||
local cap; cap="$(tool_cap opencode)"
|
||||
if printf '%s\n' "${tools[@]}" | grep -qx "OpenCode" && [[ "$agents" -gt "$cap" ]]; then
|
||||
buf+=$'\n'" ${C_YELLOW}⚠ OpenCode registers ~${cap}; ~$(( agents - cap )) of ${agents} won't load (#27988)${C_RESET}"$'\n'
|
||||
buf+=" ${C_YELLOW}⚠ OpenCode registers ~${cap}; ~$(( agents - cap )) of ${agents} won't load (#27988)${C_RESET}"$'\n'
|
||||
fi
|
||||
draw_frame "$buf"
|
||||
local key; key="$(read_key)"
|
||||
|
||||
Reference in New Issue
Block a user