ContextStudioWizard/wizard.sh
Karamelmar 120fc913f4 Warn user that first start.sh run builds the image and takes time
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 12:34:08 +01:00

167 lines
7.6 KiB
Bash
Executable file
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
# ╔══════════════════════════════════════════════════════════════════╗
# ║ Context Studio Wizard — Project Setup ║
# ╚══════════════════════════════════════════════════════════════════╝
set -uo pipefail
WIZARD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$WIZARD_DIR/lib/utils.sh"
source "$WIZARD_DIR/lib/prereqs.sh"
source "$WIZARD_DIR/lib/core.sh"
source "$WIZARD_DIR/lib/project.sh"
source "$WIZARD_DIR/lib/workflow.sh"
source "$WIZARD_DIR/lib/container.sh"
# ── Find existing projects base dir ───────────────────────────────────────
find_projects_dir() {
local candidates=("Projects" "projects" "Project" "project" "Dev" "dev" "Workspace" "workspace" "Code" "code" "src" "Src")
for candidate in "${candidates[@]}"; do
if [[ -d "$HOME/$candidate" ]]; then
echo "$HOME/$candidate"
return
fi
done
echo "$HOME/Projects"
}
# ── Project info ───────────────────────────────────────────────────────────
collect_project_info() {
header "Project Details"
ask PROJECT_NAME "Project name" ""
if [[ -z "$PROJECT_NAME" ]]; then die "Project name is required."; fi
local projects_base
projects_base="$(find_projects_dir)"
local default_dir="$projects_base/$(slugify "$PROJECT_NAME")"
ask PROJECT_DIR "Project location" "$default_dir"
if [[ -z "$PROJECT_DIR" ]]; then die "Project location is required."; fi
PROJECT_DIR="${PROJECT_DIR/#\~/$HOME}"
if [[ -e "$PROJECT_DIR" ]]; then
warn "Directory already exists: $PROJECT_DIR"
ask_yn _continue "Continue anyway?" "n"
if [[ "$_continue" != "y" ]]; then die "Aborted."; fi
fi
}
# ── Workflow source ────────────────────────────────────────────────────────
collect_workflow_info() {
header "Workflow Configuration"
ask_choice WORKFLOW_SOURCE "How do you want to configure your workflow?" \
"Generate from scratch" \
"Clone from existing repo"
if [[ "$WORKFLOW_SOURCE" == "Clone from existing repo" ]]; then
ask WORKFLOW_REPO "Workflow repo URL" ""
if [[ -z "$WORKFLOW_REPO" ]]; then die "Repo URL is required."; fi
else
ask PROJECT_DESC "Project description" "A software project"
ask TECH_STACK "Tech stack (e.g. Node.js, Rust, Python)" "Node.js"
ask_choice AGENT_PRESET "Agent preset" \
"minimal (5 agents: coordinator, 2 coders, researcher, tester)" \
"standard (9 agents: 2 coordinators, 3 coders, 2 researchers, tester, reviewer)"
case "$AGENT_PRESET" in
minimal*) AGENT_PRESET="minimal" ;;
*) AGENT_PRESET="standard" ;;
esac
fi
}
# ── Summary & confirm ──────────────────────────────────────────────────────
confirm_summary() {
header "Summary"
echo -e " ${BOLD}Project name${RESET} : $PROJECT_NAME"
echo -e " ${BOLD}Location${RESET} : $PROJECT_DIR"
echo -e " ${BOLD}Core${RESET} : $CS_CORE_DIR"
if [[ "${WORKFLOW_SOURCE:-}" == "Clone from existing repo" ]]; then
echo -e " ${BOLD}Workflow${RESET} : clone ${WORKFLOW_REPO:-}"
else
echo -e " ${BOLD}Workflow${RESET} : generate (${AGENT_PRESET:-minimal} preset)"
echo -e " ${BOLD}Description${RESET} : ${PROJECT_DESC:-}"
echo -e " ${BOLD}Tech stack${RESET} : ${TECH_STACK:-}"
fi
echo ""
ask_yn _ok "Create project?" "y"
if [[ "$_ok" != "y" ]]; then die "Aborted."; fi
}
# ── Build ──────────────────────────────────────────────────────────────────
build_project() {
header "Building Project"
local slug
slug="$(slugify "$PROJECT_NAME")"
create_project_structure "$PROJECT_DIR" "$PROJECT_NAME"
create_devcontainer "$PROJECT_DIR" "$PROJECT_NAME"
generate_container_scripts "$PROJECT_DIR" "$PROJECT_NAME" "$slug"
if [[ "${WORKFLOW_SOURCE:-}" == "Clone from existing repo" ]]; then
clone_workflow "$PROJECT_DIR" "${WORKFLOW_REPO:-}"
else
generate_workflow "$PROJECT_DIR" "$PROJECT_NAME" \
"${PROJECT_DESC:-A software project}" \
"${TECH_STACK:-Node.js}" \
"${AGENT_PRESET:-minimal}"
fi
git -C "$PROJECT_DIR" init -q
git -C "$PROJECT_DIR" add .
git -C "$PROJECT_DIR" commit -q -m "Initial project setup via Context Studio Wizard"
success "Git repo initialized"
}
# ── Done ───────────────────────────────────────────────────────────────────
print_next_steps() {
local slug
slug="$(slugify "$PROJECT_NAME")"
header "Done!"
success "Project created at: $PROJECT_DIR"
echo ""
echo -e "${BOLD}${GREEN} ➜ Enter your project now:${RESET}"
echo -e "${BOLD}${CYAN} cd \"$PROJECT_DIR\"${RESET}"
echo ""
echo -e "${BOLD}Start everything:${RESET}"
echo -e " ${CYAN}./start.sh${RESET}"
echo -e " Starts the agents container, then launches Context Studio Core on your host."
echo ""
echo -e " ${YELLOW}⚠ First run only:${RESET} the container image needs to be built."
echo -e " This downloads Node.js, Rust, Claude Code and all build tools."
echo -e " ${BOLD}Expect 515 minutes depending on your connection.${RESET}"
echo -e " Subsequent starts are instant — the image is cached."
echo ""
echo -e "${BOLD}Stop the container:${RESET}"
echo -e " ${CYAN}./stop.sh${RESET}"
echo ""
echo -e "${BOLD}How it works:${RESET}"
echo -e " • Context Studio Core runs on your host (Electron UI, no display issues)"
echo -e " • Claude Code agents run inside container ${CYAN}cs-${slug}${RESET}"
echo -e "${CYAN}bin/claude${RESET} intercepts every agent call and routes it into the container"
echo -e " • Project files are mounted at the same path on host and in container"
echo ""
echo -e "${BOLD}VS Code (for editing):${RESET}"
echo -e " ${CYAN}code \"$PROJECT_DIR\"${RESET} → \"Reopen in Container\""
echo ""
}
# ── Main ───────────────────────────────────────────────────────────────────
main() {
echo ""
echo -e "${BOLD}${CYAN}╔══════════════════════════════════════╗${RESET}"
echo -e "${BOLD}${CYAN}║ Context Studio Wizard v1.0 ║${RESET}"
echo -e "${BOLD}${CYAN}╚══════════════════════════════════════╝${RESET}"
check_prerequisites
setup_core
collect_project_info
collect_workflow_info
confirm_summary
build_project
print_next_steps
}
main "$@"