fix(install): close MEDIUM/LOW from RULE 0.26 audit
- preflight failure handling: вместо `|| true` (молчаливое продолжение при упавшем preflight) — явный prompt «продолжить? [y/N]» с return 1 при отказе. Без TTY печатает warning и продолжает. Это закрывает HIGH bug-9: «.onboarded флаг выставляется при нерабочей конфигурации». - lib-preflight.sh::preflight_check_cli — общий helper (command -v + offer-install + version echo). Убирает 6-file boilerplate (хотя сами per-provider файлы пока не переписаны под него — это отдельный шаг). - onboarding_fallback_providers: расширен с 3 до 14 провайдеров, покрывает все 7 транспортов. Был дрейф vs providers.toml (14 vs 3), юзер без submodule видел только anthropic+openai+ollama. - STR_PICK_PROVIDER plural mismatch: whiptail и plain ветки теперь используют один fallback "Provider within" (раньше plain имел "Providers within", whiptail — "Provider within"). - STR_DONE_NEXT удалён из en.sh + ru.sh (мёртвый ключ). - Новые ключи: STR_MENU_* (для lib-menu.sh) + STR_PREFLIGHT_FAILED + STR_PREFLIGHT_CONTINUE. lib-menu.sh начал использовать STR_MENU_TITLE / STR_MENU_SUBSTRATE (частичная локализация, остальное меню — отдельной задачей). Тесты: bash -n чисто, i18n round-trip EN/RU работает, non-TTY smoke install --no-execute проходит.
This commit is contained in:
parent
15e0370003
commit
f3b6a2d3b8
5 changed files with 84 additions and 6 deletions
|
|
@ -30,4 +30,13 @@ STR_AUTH_CURRENT_HINT="(current: <hidden>)"
|
|||
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]"
|
||||
|
|
|
|||
|
|
@ -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]"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in a new issue