feat(scaffold): align generated install wizard with latest TUI flow
This commit is contained in:
parent
9d862c876f
commit
3eeb2fe173
2 changed files with 185 additions and 63 deletions
|
|
@ -339,6 +339,9 @@ BINARY_NAME="{{.BinaryName}}"
|
|||
MODULE_PATH="{{.ModulePath}}"
|
||||
DEFAULT_PROFILE="{{.DefaultProfile}}"
|
||||
PROFILE_ENV="{{.ProfileEnv}}"
|
||||
PREFILL_SERVER_NAME=""
|
||||
PREFILL_PROFILE_VALUE=""
|
||||
PREFILL_COMMAND_PATH=""
|
||||
|
||||
if [ -t 2 ] && [ -z "${NO_COLOR:-}" ]; then
|
||||
C_RESET="$(printf '\033[0m')"
|
||||
|
|
@ -413,6 +416,101 @@ prompt() {
|
|||
printf "%s" "$answer"
|
||||
}
|
||||
|
||||
tty_prompt_available() {
|
||||
[ -t 2 ] && [ -r /dev/tty ] && [ -w /dev/tty ]
|
||||
}
|
||||
|
||||
menu_select() {
|
||||
local title="$1"
|
||||
shift
|
||||
local options=("$@")
|
||||
local count="${#options[@]}"
|
||||
local index=0
|
||||
local key=""
|
||||
local i=0
|
||||
local rows=$((count + 3))
|
||||
local rendered=0
|
||||
|
||||
if [ "$count" -eq 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! tty_prompt_available; then
|
||||
ui_title "$title"
|
||||
i=0
|
||||
while [ "$i" -lt "$count" ]; do
|
||||
printf " %d) %s\n" "$((i + 1))" "${options[$i]}" >&2
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
while true; do
|
||||
local raw_choice
|
||||
raw_choice="$(prompt "Choix" "1")"
|
||||
case "$raw_choice" in
|
||||
''|*[!0-9]*)
|
||||
ui_warn "Choix invalide: $raw_choice"
|
||||
;;
|
||||
*)
|
||||
if [ "$raw_choice" -ge 1 ] && [ "$raw_choice" -le "$count" ]; then
|
||||
printf "%s" "${options[$((raw_choice - 1))]}"
|
||||
return 0
|
||||
fi
|
||||
ui_warn "Choix invalide: $raw_choice"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
while true; do
|
||||
if [ "$rendered" -eq 1 ]; then
|
||||
printf "\033[%dA\033[J" "$rows" >&2 2>/dev/null || true
|
||||
fi
|
||||
ui_title "$title"
|
||||
i=0
|
||||
while [ "$i" -lt "$count" ]; do
|
||||
if [ "$i" -eq "$index" ]; then
|
||||
printf " %b› %s%b\n" "$C_BOLD$C_CYAN" "${options[$i]}" "$C_RESET" >&2
|
||||
else
|
||||
printf " %s\n" "${options[$i]}" >&2
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done
|
||||
printf "%bUtilise ↑/↓ puis Entrée.%b\n" "$C_DIM" "$C_RESET" >&2
|
||||
rendered=1
|
||||
|
||||
if ! IFS= read -rsn1 key < /dev/tty; then
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$key" in
|
||||
"")
|
||||
printf "%s" "${options[$index]}"
|
||||
return 0
|
||||
;;
|
||||
$'\x1b')
|
||||
if IFS= read -rsn2 key < /dev/tty; then
|
||||
case "$key" in
|
||||
"[A")
|
||||
if [ "$index" -eq 0 ]; then
|
||||
index=$((count - 1))
|
||||
else
|
||||
index=$((index - 1))
|
||||
fi
|
||||
;;
|
||||
"[B")
|
||||
if [ "$index" -eq $((count - 1)) ]; then
|
||||
index=0
|
||||
else
|
||||
index=$((index + 1))
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
sanitize_server_name() {
|
||||
local raw="$1"
|
||||
local sanitized
|
||||
|
|
@ -505,48 +603,46 @@ run_setup_wizard() {
|
|||
binary_path="$(resolve_binary_path)"
|
||||
|
||||
ui_info "Lancement de $BINARY_NAME setup"
|
||||
if [ -r /dev/tty ] && [ -w /dev/tty ]; then
|
||||
if [ -t 2 ] && [ -r /dev/tty ] && [ -w /dev/tty ]; then
|
||||
env "${PROFILE_ENV}=${profile}" "$binary_path" setup < /dev/tty > /dev/tty
|
||||
else
|
||||
env "${PROFILE_ENV}=${profile}" "$binary_path" setup
|
||||
fi
|
||||
ui_success "Setup termine pour le profil \"$profile\"."
|
||||
|
||||
PREFILL_SERVER_NAME="$(sanitize_server_name "$BINARY_NAME")"
|
||||
PREFILL_PROFILE_VALUE="$profile"
|
||||
PREFILL_COMMAND_PATH="$binary_path"
|
||||
}
|
||||
|
||||
collect_server_inputs() {
|
||||
local default_name
|
||||
default_name="$(sanitize_server_name "$BINARY_NAME")"
|
||||
default_name="$(sanitize_server_name "${PREFILL_SERVER_NAME:-$BINARY_NAME}")"
|
||||
SERVER_NAME="$(prompt "Nom du serveur MCP" "$default_name")"
|
||||
SERVER_NAME="$(sanitize_server_name "$SERVER_NAME")"
|
||||
|
||||
PROFILE_VALUE="$(prompt "Valeur de ${PROFILE_ENV}" "$DEFAULT_PROFILE")"
|
||||
PROFILE_VALUE="$(prompt "Valeur de ${PROFILE_ENV}" "${PREFILL_PROFILE_VALUE:-$DEFAULT_PROFILE}")"
|
||||
|
||||
local default_command
|
||||
if [ -n "${PREFILL_COMMAND_PATH:-}" ]; then
|
||||
default_command="$PREFILL_COMMAND_PATH"
|
||||
else
|
||||
default_command="$(resolve_binary_path)"
|
||||
fi
|
||||
COMMAND_PATH="$(prompt "Chemin du binaire serveur MCP" "$default_command")"
|
||||
}
|
||||
|
||||
choose_scope() {
|
||||
local selected
|
||||
while true; do
|
||||
ui_title "Scope de configuration"
|
||||
printf " 1) global (user)\n" >&2
|
||||
printf " 2) project (projet courant)\n" >&2
|
||||
selected="$(prompt "Choix" "1")"
|
||||
selected="$(menu_select "Scope de configuration" "global (user)" "project (projet courant)")"
|
||||
case "$selected" in
|
||||
1)
|
||||
"global (user)")
|
||||
printf "global"
|
||||
return
|
||||
;;
|
||||
2)
|
||||
printf "project"
|
||||
return
|
||||
;;
|
||||
*)
|
||||
ui_warn "Choix invalide: $selected"
|
||||
printf "project"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
apply_claude_mcp() {
|
||||
|
|
@ -567,8 +663,9 @@ apply_claude_mcp() {
|
|||
claude mcp add \
|
||||
--transport stdio \
|
||||
--scope "$claude_scope" \
|
||||
-e "${PROFILE_ENV}=${PROFILE_VALUE}" \
|
||||
"$SERVER_NAME" -- "$COMMAND_PATH" mcp
|
||||
"$SERVER_NAME" \
|
||||
--env "${PROFILE_ENV}=${PROFILE_VALUE}" \
|
||||
-- "$COMMAND_PATH" mcp
|
||||
|
||||
ui_success "Serveur \"$SERVER_NAME\" configure dans Claude ($claude_scope)."
|
||||
}
|
||||
|
|
@ -667,48 +764,69 @@ print_header() {
|
|||
printf "%bMCP Install Wizard%b for %b%s%b\n" "$C_BOLD$C_MAGENTA" "$C_RESET" "$C_BOLD" "$BINARY_NAME" "$C_RESET" >&2
|
||||
printf "%bFramework module:%b %s\n" "$C_DIM" "$C_RESET" "$MODULE_PATH" >&2
|
||||
ui_line
|
||||
printf "Choisis une action:\n" >&2
|
||||
printf " 1) Installer/mettre a jour le binaire + setup\n" >&2
|
||||
printf " 2) Configurer Claude Code (apply direct)\n" >&2
|
||||
printf " 3) Configurer Codex (apply direct)\n" >&2
|
||||
printf " 4) Generer JSON MCP manuel\n" >&2
|
||||
printf " 5) Quitter\n" >&2
|
||||
printf "%bSelectionne une action dans le menu interactif.%b\n" "$C_DIM" "$C_RESET" >&2
|
||||
}
|
||||
|
||||
post_setup_configure_mcp() {
|
||||
ui_title "Configuration MCP apres setup"
|
||||
local next_action
|
||||
next_action="$(menu_select \
|
||||
"Configurer le MCP maintenant ?" \
|
||||
"Configurer Claude Code (apply direct)" \
|
||||
"Configurer Codex (apply direct)" \
|
||||
"Generer JSON MCP manuel" \
|
||||
"Terminer sans config MCP")"
|
||||
printf "\n" >&2
|
||||
|
||||
case "$next_action" in
|
||||
"Configurer Claude Code (apply direct)")
|
||||
apply_claude_mcp
|
||||
;;
|
||||
"Configurer Codex (apply direct)")
|
||||
apply_codex_mcp
|
||||
;;
|
||||
"Generer JSON MCP manuel")
|
||||
ui_info "JSON MCP genere sur stdout."
|
||||
print_mcp_json
|
||||
;;
|
||||
*)
|
||||
ui_info "Setup termine sans configuration MCP additionnelle."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main() {
|
||||
while true; do
|
||||
print_header
|
||||
local choice
|
||||
choice="$(prompt "Choix" "1")"
|
||||
|
||||
local action
|
||||
action="$(menu_select \
|
||||
"Choisis une action" \
|
||||
"Installer/mettre a jour le binaire + setup" \
|
||||
"Configurer Claude Code (apply direct)" \
|
||||
"Configurer Codex (apply direct)" \
|
||||
"Generer JSON MCP manuel" \
|
||||
"Quitter")"
|
||||
printf "\n" >&2
|
||||
|
||||
case "$choice" in
|
||||
1)
|
||||
case "$action" in
|
||||
"Installer/mettre a jour le binaire + setup")
|
||||
run_setup_wizard
|
||||
return
|
||||
post_setup_configure_mcp
|
||||
;;
|
||||
2)
|
||||
"Configurer Claude Code (apply direct)")
|
||||
apply_claude_mcp
|
||||
return
|
||||
;;
|
||||
3)
|
||||
"Configurer Codex (apply direct)")
|
||||
apply_codex_mcp
|
||||
return
|
||||
;;
|
||||
4)
|
||||
"Generer JSON MCP manuel")
|
||||
ui_info "JSON MCP genere sur stdout."
|
||||
print_mcp_json
|
||||
return
|
||||
;;
|
||||
5)
|
||||
ui_warn "Annule."
|
||||
return
|
||||
;;
|
||||
*)
|
||||
ui_warn "Choix invalide: $choice"
|
||||
ui_warn "Annule."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
|
|||
|
|
@ -121,9 +121,13 @@ func TestGenerateCreatesRecommendedSkeleton(t *testing.T) {
|
|||
`MODULE_PATH="example.com/acme/my-mcp"`,
|
||||
`go install "${MODULE_PATH}/cmd/${BINARY_NAME}@latest"`,
|
||||
"MCP Install Wizard",
|
||||
`menu_select() {`,
|
||||
`Utilise ↑/↓ puis Entrée.`,
|
||||
`Configurer le MCP maintenant ?`,
|
||||
`claude mcp add \`,
|
||||
`--transport stdio \`,
|
||||
`--scope "$claude_scope" \`,
|
||||
`--env "${PROFILE_ENV}=${PROFILE_VALUE}" \`,
|
||||
`codex mcp add \`,
|
||||
`Dossier projet cible pour .codex/config.toml`,
|
||||
`[mcp_servers.%s]`,
|
||||
|
|
|
|||
Loading…
Reference in a new issue