Session WebUI: - Add `web_ui` flag to session create — launches claude-code-ui in pod on port 3001 - Install @siteboon/claude-code-ui in claudebox Dockerfile, expose port 3001 - Migration 027: add web_ui column to sessions table - startWebUI/stopWebUI fire-and-forget helpers in SessionsHandler - Service selects preview port 3001 (web UI) vs 8080 (sidecar) based on flag Aeries Daeya cookbook: - Add cookbooks/trees/aeries-daeya.yaml: privacy-first avatar social platform (infra → avatar data model → AI generation pipeline → studio UI) - Add cookbooks/scripts/aeries-daeya-test.sh: run/status/diagnose/teardown harness - Fix race condition in common.sh wait_for_pipeline: detect already-running pipelines at startup and track directly instead of waiting for a newer one Docs/tooling: - Add SDK Update Workflow section to CLAUDE.md - Add `make sdk` and `make sdk-check` targets for OpenAPI spec management Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
148 lines
5.3 KiB
Bash
Executable File
148 lines
5.3 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Aeries Daeya E2E Test Script
|
|
# Privacy-first avatar social platform: character creation, AI styling from photos,
|
|
# mutation explorer, album management.
|
|
#
|
|
# Usage: ./cookbooks/scripts/aeries-daeya-test.sh <command> <project-name>
|
|
# Commands: run, status, diagnose, teardown
|
|
#
|
|
# Examples:
|
|
# ./cookbooks/scripts/aeries-daeya-test.sh run my-daeya
|
|
# ./cookbooks/scripts/aeries-daeya-test.sh run my-daeya --auto-teardown
|
|
# AUTO_TEARDOWN=true ./cookbooks/scripts/aeries-daeya-test.sh run my-daeya
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$SCRIPT_DIR/common.sh"
|
|
|
|
# Parse --auto-teardown flag from args
|
|
ARGS=("$@")
|
|
for i in "${!ARGS[@]}"; do
|
|
if [[ "${ARGS[$i]}" == "--auto-teardown" ]]; then
|
|
AUTO_TEARDOWN="true"
|
|
unset 'ARGS[$i]'
|
|
fi
|
|
done
|
|
ARGS=("${ARGS[@]}")
|
|
|
|
COMMAND="${ARGS[0]:-}"
|
|
PROJECT_NAME="${ARGS[1]:-}"
|
|
|
|
register_cleanup_trap
|
|
|
|
if [[ -z "$COMMAND" || -z "$PROJECT_NAME" ]]; then
|
|
echo "Usage: $0 <command> <project-name>"
|
|
echo "Commands:"
|
|
echo " run - Deploy full aeries-daeya platform via tree runner"
|
|
echo " status - Check project and component status"
|
|
echo " diagnose - Deep diagnostic of pipeline and site issues"
|
|
echo " teardown - Delete the project and all resources"
|
|
exit 1
|
|
fi
|
|
|
|
run_flow() {
|
|
print_header "Aeries Daeya: Privacy-First Avatar Platform"
|
|
|
|
echo "Running tree: aeries-daeya for project: $PROJECT_NAME"
|
|
echo ""
|
|
echo " Phase 1 — Infrastructure (DB + Redis + service + worker + app)"
|
|
echo " Phase 2 — Avatar & Look Data Model (characters, looks, albums, posts, mutations)"
|
|
echo " Phase 3 — AI Generation Pipeline (portrait gen, outfit styling, mutation explorer)"
|
|
echo " Phase 4 — Studio UI (creation wizard, mutation explorer, look panel, albums)"
|
|
echo ""
|
|
|
|
"$SCRIPT_DIR/tree-runner.sh" run aeries-daeya \
|
|
--project-name "$PROJECT_NAME" \
|
|
${AUTO_TEARDOWN:+--auto-teardown}
|
|
|
|
DOMAIN=$(api_call GET "/project/$PROJECT_NAME" | jq -r '.data.domain // empty')
|
|
|
|
if [[ -n "$DOMAIN" ]]; then
|
|
print_success "Aeries Daeya is live at https://$DOMAIN"
|
|
echo ""
|
|
echo " Studio: https://$DOMAIN"
|
|
echo " API health: https://$DOMAIN/api/daeya-api/health"
|
|
echo " Characters: https://$DOMAIN/api/daeya-api/characters (requires auth)"
|
|
echo ""
|
|
echo " Flow:"
|
|
echo " 1. Open https://$DOMAIN → login with OTP"
|
|
echo " 2. Create Character → 4-step wizard (describe, shape, soul, generate)"
|
|
echo " 3. Open Character → use Mutation Explorer to adjust skin tone, background, lighting"
|
|
echo " 4. Add Look → upload a photo of an outfit to style on your character"
|
|
fi
|
|
}
|
|
|
|
check_status() {
|
|
print_header "Project Status: $PROJECT_NAME"
|
|
|
|
local project
|
|
project=$(api_call GET "/project/$PROJECT_NAME")
|
|
local domain
|
|
domain=$(echo "$project" | jq -r '.data.domain // "unknown"')
|
|
local status
|
|
status=$(echo "$project" | jq -r '.data.status // "unknown"')
|
|
|
|
echo " Domain: $domain"
|
|
echo " Status: $status"
|
|
echo ""
|
|
|
|
print_header "Components"
|
|
api_call GET "/projects/$PROJECT_NAME/components" | jq -r '.data[] | " \(.name) (\(.type)): \(.status)"' 2>/dev/null || echo " (no components)"
|
|
|
|
echo ""
|
|
print_header "Recent Pipelines"
|
|
api_call GET "/projects/$PROJECT_NAME/pipelines" | jq -r '.data[0:3][] | " [\(.status)] \(.number) — \(.created_at)"' 2>/dev/null || echo " (no pipelines)"
|
|
|
|
echo ""
|
|
if [[ "$domain" != "unknown" ]]; then
|
|
local health_status
|
|
health_status=$(curl -sf "https://$domain/api/daeya-api/health" 2>/dev/null | jq -r '.data.status // "unreachable"' || echo "unreachable")
|
|
echo " daeya-api health: $health_status"
|
|
fi
|
|
}
|
|
|
|
diagnose() {
|
|
print_header "Diagnostic: $PROJECT_NAME"
|
|
|
|
local domain
|
|
domain=$(api_call GET "/project/$PROJECT_NAME" | jq -r '.data.domain // empty')
|
|
|
|
diagnose_pipeline_failure "$PROJECT_NAME"
|
|
|
|
if [[ -n "$domain" ]]; then
|
|
diagnose_site_failure "$domain" "$PROJECT_NAME"
|
|
fi
|
|
|
|
print_diagnostic_header "AI Generation Checks"
|
|
echo ""
|
|
echo " If characters are stuck in 'pending' status:"
|
|
print_fix "media-worker may not be running or Redis connection may be broken"
|
|
print_cmd "kubectl logs -n projects -l project=$PROJECT_NAME,component=media-worker --tail=50"
|
|
echo ""
|
|
echo " If mutation explorer generates but never shows result:"
|
|
print_fix "SSE channel:daeya subscription may not be connected"
|
|
print_cmd "curl -N -H 'Authorization: Bearer <token>' https://$domain/api/daeya-api/events/channel:daeya"
|
|
echo ""
|
|
echo " If look generation fails with photo upload:"
|
|
print_fix "GEMINI_API_KEY may not be injected or vision endpoint unreachable"
|
|
print_cmd "kubectl exec -n projects deploy/$PROJECT_NAME-media-worker -- env | grep GEMINI"
|
|
}
|
|
|
|
teardown() {
|
|
print_header "Tearing down: $PROJECT_NAME"
|
|
|
|
local result
|
|
result=$(api_call DELETE "/project/$PROJECT_NAME")
|
|
print_success "Project $PROJECT_NAME deleted"
|
|
echo "$result" | jq -r '.message // empty' 2>/dev/null || true
|
|
}
|
|
|
|
case "$COMMAND" in
|
|
run) run_flow ;;
|
|
status) check_status ;;
|
|
diagnose) diagnose ;;
|
|
teardown) teardown ;;
|
|
*) echo "Unknown command: $COMMAND"; exit 1 ;;
|
|
esac
|