diff --git a/install/i18n/en.sh b/install/i18n/en.sh index a5c4025..750683f 100644 --- a/install/i18n/en.sh +++ b/install/i18n/en.sh @@ -30,4 +30,13 @@ STR_AUTH_CURRENT_HINT="(current: )" STR_DONE_TITLE="Onboarding complete" STR_DONE_CONFIG="config:" STR_DONE_SECRETS="secrets:" -STR_DONE_NEXT="Next: run ./install.sh or restart this script to apply profile" + +# Profile menu (lib-menu.sh strings) +STR_MENU_TITLE="KeiSeiKit Installer" +STR_MENU_SUBSTRATE="Substrate baseline (always installed):" +STR_MENU_PROFILE_PROMPT="Choose install profile:" +STR_MENU_CONFIRM="Confirm selection?" + +# Preflight warnings +STR_PREFLIGHT_FAILED="Preflight failed — provider may not work." +STR_PREFLIGHT_CONTINUE="Continue anyway? [y/N]" diff --git a/install/i18n/ru.sh b/install/i18n/ru.sh index cb45d03..1764178 100644 --- a/install/i18n/ru.sh +++ b/install/i18n/ru.sh @@ -30,4 +30,13 @@ STR_AUTH_CURRENT_HINT="(текущее: <скрыто>)" STR_DONE_TITLE="Первичная настройка завершена" STR_DONE_CONFIG="конфиг:" STR_DONE_SECRETS="секреты:" -STR_DONE_NEXT="Дальше: запустите ./install.sh или перезапустите этот скрипт для установки профиля" + +# Меню профилей (lib-menu.sh) +STR_MENU_TITLE="Установщик KeiSeiKit" +STR_MENU_SUBSTRATE="Базовая часть (ставится всегда):" +STR_MENU_PROFILE_PROMPT="Выберите профиль установки:" +STR_MENU_CONFIRM="Подтвердить выбор?" + +# Preflight-предупреждения +STR_PREFLIGHT_FAILED="Preflight упал — провайдер может не работать." +STR_PREFLIGHT_CONTINUE="Продолжить всё равно? [y/N]" diff --git a/install/lib-menu.sh b/install/lib-menu.sh index 0072cc3..e8ff90e 100644 --- a/install/lib-menu.sh +++ b/install/lib-menu.sh @@ -69,10 +69,10 @@ menu_whiptail_custom() { # plain-text profile picker → profile name. Exits 1 on cancel. menu_plain_profile() { echo "============================================================" >&2 - echo " KeiSeiKit Installer" >&2 + echo " ${STR_MENU_TITLE:-KeiSeiKit Installer}" >&2 echo "============================================================" >&2 echo >&2 - echo " Substrate baseline (ALWAYS installed, regardless of profile):" >&2 + echo " ${STR_MENU_SUBSTRATE:-Substrate baseline (ALWAYS installed):}" >&2 echo " • 37 agent manifests • 67 skills • 39 hooks" >&2 echo " • 82 blocks • 16 caps • 7 roles" >&2 echo " • 11 cross-tool bridges (Cursor / Copilot / Codex / Aider / …)" >&2 diff --git a/install/lib-onboarding.sh b/install/lib-onboarding.sh index 6a88cd7..e724860 100644 --- a/install/lib-onboarding.sh +++ b/install/lib-onboarding.sh @@ -59,10 +59,25 @@ onboarding_list_providers() { } # Fallback если submodule не подтянут. +# Покрывает 7 транспортов (direct-api / aws / azure / vertex / local / proxy +# / subscription) минимальными представителями. Используется только когда +# providers.toml отсутствует — синхронизировать ручно если добавится новый +# транспорт-тип в реестр. onboarding_fallback_providers() { printf "anthropic\tdirect-api\tAnthropic (Direct API)\tANTHROPIC_API_KEY\n" + printf "anthropic-bedrock\taws-bedrock\tAnthropic (AWS Bedrock)\tAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION\n" printf "openai\tdirect-api\tOpenAI (Direct API)\tOPENAI_API_KEY\n" + printf "openai-azure\tazure-openai\tOpenAI (Azure)\tAZURE_OPENAI_API_KEY,AZURE_OPENAI_ENDPOINT,AZURE_OPENAI_DEPLOYMENT\n" + printf "xai\tdirect-api\txAI\tXAI_API_KEY\n" + printf "deepseek\tdirect-api\tDeepSeek\tDEEPSEEK_API_KEY\n" + printf "google\tdirect-api\tGoogle Gemini (Direct API)\tGEMINI_API_KEY\n" + printf "google-vertex\tgoogle-vertex\tGoogle Gemini (Vertex AI)\tGOOGLE_APPLICATION_CREDENTIALS,GCP_PROJECT_ID,GCP_REGION\n" printf "ollama-local\tlocal\tOllama (local)\t_\n" + printf "mlx-local\tlocal\tMLX (Apple silicon local)\t_\n" + printf "lmstudio-local\tlocal\tLM Studio (local)\t_\n" + printf "litellm-proxy\tproxy\tLiteLLM proxy (keisei.app)\tKEI_LITELLM_KEY\n" + printf "openrouter\tproxy\tOpenRouter\tOPENROUTER_API_KEY\n" + printf "codex\tsubscription\tOpenAI Codex (ChatGPT OAuth)\t_\n" } # Уникальные транспорты — для первого экрана выбора. @@ -183,7 +198,8 @@ onboarding_pick_provider() { || ONBOARDING_PROVIDER=$(echo "$rows" | head -1 | awk -F'\t' '{print $1}') else echo "" >&2 - echo "${STR_PICK_PROVIDER:-Providers within} $ONBOARDING_TRANSPORT:" >&2 + # Используем единый fallback что и для whiptail — устраняем plural mismatch. + echo "${STR_PICK_PROVIDER:-Provider within} $ONBOARDING_TRANSPORT:" >&2 declare -a ids=() local i=1 while IFS=$'\t' read -r id dn ae; do @@ -337,7 +353,27 @@ onboarding_run() { # Preflight — проверка CLI/daemon до сбора ключей. # Для direct-api провайдеров файла preflight нет → silent pass. if command -v preflight_run >/dev/null 2>&1; then - preflight_run "$ONBOARDING_PROVIDER" || true + if ! preflight_run "$ONBOARDING_PROVIDER"; then + # Provider preflight failed (CLI missing / daemon down / no creds). + # Не молчим — спрашиваем юзера, иначе onboarding закончится + # с .onboarded флагом для нерабочей конфигурации (HIGH аудит-9). + echo "" >&2 + echo " ⚠ ${STR_PREFLIGHT_FAILED:-Preflight failed — provider may not work.}" >&2 + if [ -t 0 ] && [ -t 1 ]; then + read -r -p " ${STR_PREFLIGHT_CONTINUE:-Continue anyway? [y/N]} " _ans + case "$_ans" in + y|Y|yes|да|Да) + echo " → продолжаю; ключи запишутся но runtime может упасть." >&2 + ;; + *) + echo " → прервано; флаг .onboarded НЕ выставляется, перезапустите." >&2 + return 1 + ;; + esac + else + echo " → non-TTY, продолжаю — настройте CLI вручную потом." >&2 + fi + fi fi onboarding_collect_auth onboarding_write_secrets diff --git a/install/lib-preflight.sh b/install/lib-preflight.sh index ae15e99..722b226 100644 --- a/install/lib-preflight.sh +++ b/install/lib-preflight.sh @@ -50,6 +50,30 @@ preflight_offer_install() { fi } +# Универсальный helper для типового CLI-чека (command -v + offer-install + version). +# Используется per-provider preflight файлами чтобы убрать boilerplate. +# +# Аргументы: +# $1 — имя CLI (для сообщений), например "aws CLI" +# $2 — бинарь (для command -v), например "aws" +# $3 — install_cmd (для preflight_offer_install) +# $4 — version_cmd (для печати при success), например "aws --version" +# +# Возврат: 0 если CLI есть, 1 если нет и юзер не поставил. +preflight_check_cli() { + local label="$1" + local bin="$2" + local install_cmd="$3" + local version_cmd="$4" + if ! command -v "$bin" >/dev/null 2>&1; then + preflight_offer_install "$label" "$install_cmd" || return 1 + # После install проверяем что бинарь появился в PATH. + command -v "$bin" >/dev/null 2>&1 || return 1 + fi + echo " ✓ $label: $(eval "$version_cmd" 2>&1 | head -1)" >&2 + return 0 +} + # Главный диспетчер. Вызывается из onboarding между pick_model и collect_auth. preflight_run() { local provider="$1"