ContextStudioWizard/lib/prereqs.sh
Karamelmar 7c9b61bfce Fix end-to-end startup: project registration, credentials, trust dialog, ready marker
- start.sh: auto-register project in ~/.config/context-studio/projects/ before
  launching Electron — without this acquireProjectLock() silently skips writing
  the lock file, waitForServers() never finds the registry port, all agent ports
  stay null (localhost:null errors)

- start.sh: mount all known Claude Code credential locations into container
  (~/.claude/.credentials.json, ~/.claude.json, $CLAUDE_CONFIG_DIR variants)
  not just ~/.anthropic which was empty on this system

- bin/claude: create /tmp/cs-ready-<agentId> on host after 3s delay so CS Core's
  CLI ready marker poll resolves instead of timing out after 10s

- workflow.sh: add hasTrustDialogAccepted:true to all agent settings.json so
  claude goes straight to priming without the folder trust dialog

- prereqs.sh: add ensure_api_key() — checks all credential locations, prompts
  with masked input if none found, offers to save to shell profile

- wizard.sh: trap SIGINT for graceful abort — gum confirm popup, reverts created
  project dir and cloned core dir, leaves installed packages untouched

- core.sh: set _WIZARD_CORE_CLONED=true before clone for cleanup tracking

- electron-config.js: increase serverStartupTimeout 30s→90s (config file in
  core/config/, not source — safe to edit)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 21:20:25 +01:00

170 lines
5.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.

#!/usr/bin/env bash
# prereqs.sh — detect distro, install missing prerequisites
detect_distro() {
if command -v pacman &>/dev/null; then echo "arch";
elif command -v apt-get &>/dev/null; then echo "debian";
elif command -v dnf &>/dev/null; then echo "rhel";
elif command -v yum &>/dev/null; then echo "rhel-yum";
elif command -v zypper &>/dev/null; then echo "suse";
else echo "unknown";
fi
}
install_pkg() {
local pkg="$1"
local distro
distro="$(detect_distro)"
case "$distro" in
arch) sudo pacman -Sy --noconfirm "$pkg" ;;
debian) sudo apt-get update -qq && sudo apt-get install -y "$pkg" ;;
rhel) sudo dnf install -y "$pkg" ;;
rhel-yum) sudo yum install -y "$pkg" ;;
suse) sudo zypper install -y "$pkg" ;;
*) die "Unsupported distro — please install $pkg manually." ;;
esac
}
ensure_git() {
if command -v git &>/dev/null; then
success "git $(git --version | awk '{print $3}')"
return
fi
warn "git not found."
ask_yn _install "Install git now?" "y"
if [[ "$_install" != "y" ]]; then die "git is required."; fi
gum spin --spinner dot --spinner.foreground "$C_MAUVE" \
--title " Installing git..." --title.foreground "$C_SKY" \
-- bash -c "$(declare -f install_pkg detect_distro); install_pkg git"
command -v git &>/dev/null || die "git installation failed."
success "git $(git --version | awk '{print $3}')"
}
ensure_container_runtime() {
if command -v podman &>/dev/null; then
CONTAINER_CMD="podman"
success "podman $(podman --version | awk '{print $3}')"
return
fi
if command -v docker &>/dev/null; then
CONTAINER_CMD="docker"
success "docker $(docker --version | awk '{print $3}' | tr -d ',')"
return
fi
warn "No container runtime found."
echo ""
gum style --foreground "$C_SKY" --margin "0 4" \
"podman — recommended (rootless, no daemon)" \
"docker — alternative"
echo ""
ask_choice _runtime "Which would you like to install?" \
"podman (recommended)" \
"docker"
local runtime_choice="$_runtime"
case "$runtime_choice" in
podman*) _install_podman; CONTAINER_CMD="podman" ;;
docker*) _install_docker; CONTAINER_CMD="docker" ;;
esac
command -v "$CONTAINER_CMD" &>/dev/null \
|| die "$CONTAINER_CMD installation failed. Please install manually."
success "$CONTAINER_CMD installed"
}
_install_podman() {
local distro
distro="$(detect_distro)"
gum spin --spinner dot --spinner.foreground "$C_MAUVE" \
--title " Installing podman..." --title.foreground "$C_SKY" \
-- bash -c "$(declare -f install_pkg detect_distro); install_pkg podman"
}
_install_docker() {
local distro
distro="$(detect_distro)"
case "$distro" in
arch) install_pkg docker ;;
debian) install_pkg docker.io ;;
rhel) install_pkg docker ;;
rhel-yum) install_pkg docker ;;
suse) install_pkg docker ;;
*) die "Unsupported distro — install docker manually." ;;
esac
sudo systemctl enable --now docker 2>/dev/null || true
sudo usermod -aG docker "$USER" 2>/dev/null || true
warn "Added $USER to docker group — log out and back in for it to take effect."
}
ensure_api_key() {
if [[ -n "${ANTHROPIC_API_KEY:-}" ]]; then
success "ANTHROPIC_API_KEY is set"
return
fi
# Resolve config dir — CLAUDE_CONFIG_DIR overrides default ~/.claude
local claude_dir="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
local creds_file=""
if [[ -f "$claude_dir/.credentials.json" ]]; then creds_file="$claude_dir/.credentials.json"
elif [[ -f "$HOME/.claude.json" ]]; then creds_file="$HOME/.claude.json"
elif [[ -f "$claude_dir/.claude.json" ]]; then creds_file="$claude_dir/.claude.json"
elif [[ -f "$HOME/.anthropic/.credentials.json" ]]; then creds_file="$HOME/.anthropic/.credentials.json"
fi
if [[ -n "$creds_file" ]]; then
success "Anthropic credentials found ($creds_file)"
return
fi
warn "ANTHROPIC_API_KEY is not set."
echo ""
gum style --foreground "$C_SKY" --margin "0 4" \
"Claude Code needs an Anthropic API key to run inside the container." \
"Get one at: https://console.anthropic.com/settings/api-keys"
echo ""
local key
key=$(gum input \
--password \
--placeholder "sk-ant-..." \
--prompt " " \
--prompt.foreground "$C_MAUVE" \
--cursor.foreground "$C_MAUVE" \
--header " Anthropic API key" \
--header.foreground "$C_SKY" \
--width 70) || true
if [[ -z "$key" ]]; then
warn "No API key entered — set ANTHROPIC_API_KEY before running ./start.sh"
return
fi
export ANTHROPIC_API_KEY="$key"
success "ANTHROPIC_API_KEY set for this session"
ask_yn _save "Save to shell profile (~/.zshrc / ~/.bashrc)?" "y"
if [[ "$_save" == "y" ]]; then
local profile
if [[ "$SHELL" == */zsh ]]; then
profile="$HOME/.zshrc"
else
profile="$HOME/.bashrc"
fi
if grep -q "ANTHROPIC_API_KEY" "$profile" 2>/dev/null; then
warn "ANTHROPIC_API_KEY already in $profile — not adding again."
else
printf '\nexport ANTHROPIC_API_KEY="%s"\n' "$key" >> "$profile"
success "Saved to $profile"
fi
fi
}
check_prerequisites() {
header "Prerequisites"
ensure_git
ensure_container_runtime
ensure_api_key
}