KeiSeiKit-1.0/install/lib-onboarding.sh
KeiSei84 6d68a3f1ad
Some checks are pending
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / preflight (push) Waiting to run
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / vps-smoke (push) Waiting to run
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:frustration-matrix,kei-frustration-loop,kei-skill-importer,kei-projects-index,kei-projects-watcher,kei-gdrive-import,kei-leak-matrix,kei-skills,kei-gateway,kei-cron-scheduler,kei-export-trajectories,kei-backend-daytona,kei-d… (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-compute-baremetal,kei-compute-vultr,kei-compute-linode,kei-compute-digitalocean,kei-svc-systemd,kei-llm-bridge-mlx name:hosted-sleep-compute]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-diff,kei-scheduler,kei-watch,kei-prune,kei-discover,kei-brain-view,kei-hibernate,kei-ledger-sign,kei-fork name:wave13-15]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-git-gitea,kei-git-forgejo,kei-git-gitlab,kei-git-bitbucket,kei-memory-sled,kei-memory-redis,kei-memory-postgres,kei-memory-sqlite,kei-auth-google,kei-auth-apple,kei-auth-magiclink,kei-auth-webauthn,kei-notify-slack,kei-n… (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-ledger,kei-migrate,kei-changelog,kei-memory,kei-store,kei-conflict-scan,kei-refactor-engine,kei-graph-check,kei-shared,kei-dna-index,kei-pet name:core]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-machine-probe,kei-llm-ollama,kei-llm-llamacpp,kei-llm-mlx,kei-llm-router,kei-model name:llm-stack]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:kei-router,kei-sage,kei-task,kei-chat-store,kei-crossdomain,kei-search-core,kei-content-store,kei-social-store,kei-curator,kei-auth,kei-artifact name:mcp-lbm]) (push) Blocked by required conditions
CI (Forgejo Actions — self-hosted runner on Mac, host mode) / rust-primitives (map[crates:keisei,kei-forge,kei-runtime,kei-runtime-core,kei-atom-discovery,kei-agent-runtime,kei-capability,kei-provision,kei-entity-store,kei-pipe,kei-cache,kei-spawn,kei-replay name:atom-substrate]) (push) Blocked by required conditions
fix(onboarding): no crash on text input, Claude Code default, explanations
Three issues a real curl|bash user hit:

1. CRASH: typing a word (e.g. "claude") at any menu → $((ans-1)) treats it as a
   variable in bash arithmetic → "unbound variable" under set -u → install dies.
   Added _onb_read_choice (numeric+range validation, re-prompt) for all 4 menus.

2. No Claude under subscription: the kit installs into Claude Code yet the wizard
   offered only OpenAI Codex under subscription. Added claude-code provider
   (bumped kei-registries submodule c559065→b904993) + made subscription the
   default transport and claude-code the default provider — Enter,Enter,Enter
   lands on Claude Code (no API key).

3. install died at line 178 for any no-key provider (claude-code/codex/local):
   onboarding_run ended on a `&&` that is false when there are no auth keys →
   returned 1 → set -e aborted. Added explicit `return 0`.

Plus per-step explanations (en+ru) and auto-select when a step has one option.
Verified piped-under-pty: Enter-defaults → Claude Code, junk input → re-prompt
(0 crashes), full install completes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:42:50 +08:00

103 lines
4.6 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# shellcheck shell=bash
# lib-onboarding.sh — мастер первичной настройки (тонкий оркестратор).
#
# Иерархия: язык → транспорт → провайдер → модель → preflight → ключи.
#
# Constructor Pattern: этот файл — только координация. Логика по слоям:
# lib-onboarding-registry.sh — парсеры providers/models.toml + fallback
# lib-onboarding-ui.sh — pick_* функции (whiptail/bash select)
# lib-onboarding-state.sh — запись secrets/.env + onboarding.toml + флаг
# lib-preflight.sh — провайдер-специфичные CLI-проверки
# lib-i18n.sh — STR_* словарь + load_lang
#
# Источник: $KIT_DIR/_blocks/registries/{providers,models}.toml (submodule
# kei-registries). Если submodule не подтянут — fallback (см. registry.sh).
#
# Skip: $ONBOARDED_FLAG, env KEISEI_SKIP_ONBOARD=1, non-TTY.
# Глобалы заполняемые мастером.
ONBOARDING_LANG=""
ONBOARDING_TRANSPORT=""
ONBOARDING_PROVIDER=""
ONBOARDING_MODEL=""
declare -a ONBOARDING_AUTH_ENV_KEYS=()
declare -a ONBOARDING_AUTH_ENV_VALUES=()
ONBOARDED_FLAG="$HOME/.claude/.onboarded"
ONBOARDING_CONFIG="$HOME/.claude/config/onboarding.toml"
SECRETS_ENV="$HOME/.claude/secrets/.env"
REGISTRY_PROVIDERS="$KIT_DIR/_blocks/registries/providers.toml"
REGISTRY_MODELS="$KIT_DIR/_blocks/registries/models.toml"
# Подкубы (sourced параллельно — функции расходятся по namespace без коллизий).
# shellcheck source=install/lib-onboarding-registry.sh
[ -f "$LIB_DIR/lib-onboarding-registry.sh" ] && source "$LIB_DIR/lib-onboarding-registry.sh"
# shellcheck source=install/lib-onboarding-ui.sh
[ -f "$LIB_DIR/lib-onboarding-ui.sh" ] && source "$LIB_DIR/lib-onboarding-ui.sh"
# shellcheck source=install/lib-onboarding-state.sh
[ -f "$LIB_DIR/lib-onboarding-state.sh" ] && source "$LIB_DIR/lib-onboarding-state.sh"
# Skip-логика.
onboarding_should_run() {
[ -f "$ONBOARDED_FLAG" ] && return 1
[ "${KEISEI_SKIP_ONBOARD:-}" = "1" ] && return 1
# Interactive iff stdin is a terminal. We deliberately do NOT require -t 1:
# the curl|bash bootstrapper (web-install.sh) tees stdout to a logfile, so
# -t 1 is false even in an interactive session. Prompts go to stderr, input
# reads from stdin — an interactive stdin is the only real requirement.
[ ! -t 0 ] && return 1
return 0
}
# Оркестратор: 5 шагов + preflight + запись.
onboarding_run() {
onboarding_should_run || return 0
if command -v say >/dev/null 2>&1; then
say "${STR_ONBOARDING_INTRO:-Onboarding wizard (5 steps)}"
else
echo "── KeiSei: ${STR_ONBOARDING_INTRO:-onboarding (5 steps)} ──" >&2
fi
onboarding_pick_language
onboarding_pick_transport
onboarding_pick_provider
onboarding_pick_model
# Preflight — провайдер-специфичная проверка CLI/daemon до сбора ключей.
if command -v preflight_run >/dev/null 2>&1; then
if ! preflight_run "$ONBOARDING_PROVIDER"; then
echo "" >&2
echo "${STR_PREFLIGHT_FAILED:-Preflight failed — provider may not work.}" >&2
if [ -t 0 ]; then # stdin-only: stdout may be tee'd in curl|bash
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
onboarding_write_config
if command -v say >/dev/null 2>&1; then
say "${STR_DONE_TITLE:-onboarding complete}: $ONBOARDING_TRANSPORT / $ONBOARDING_PROVIDER / $ONBOARDING_MODEL"
say " ${STR_DONE_CONFIG:-config:} $ONBOARDING_CONFIG"
[ "${#ONBOARDING_AUTH_ENV_KEYS[@]}" -gt 0 ] && say " ${STR_DONE_SECRETS:-secrets:} $SECRETS_ENV (chmod 600)"
fi
# MUST end on success: the last statement above is a short-circuit `&&` that
# evaluates false when the provider has no auth keys (claude-code / codex /
# local) → function would return 1 → `set -e` aborts the whole install at the
# onboarding_run call. Subscription/local providers are exactly the no-key case.
return 0
}