-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdemo.sh
More file actions
executable file
·165 lines (145 loc) · 4.92 KB
/
Copy pathdemo.sh
File metadata and controls
executable file
·165 lines (145 loc) · 4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/env bash
# ============================================================================
# AI-Factory — one-command demo (Docker + enqueue product + open admin)
# ============================================================================
# Prerequisites: Docker, curl, jq OR python3; image/container from ./run.sh
#
# Usage:
# ./demo.sh [--landing] [--no-open] [--compose] "your idea here"
#
# --landing brochure/marketing_landing only (faster). Default profile is full_software.
# --no-open do not open a browser
# --compose force DEMO_BASE_URL=http://localhost:9080 (Compose UI port)
#
# Environment:
# DEMO_BASE_URL e.g. http://localhost:8080 (default: auto 8080 then 9080)
# DEMO_ADMIN_PASSWORD admin password (required; or read bootstrap_admin.txt)
# DEMO_CONTAINER_NAME container name to wait on (default: ai-factory)
# ============================================================================
set -euo pipefail
PROFILE="full_software"
OPEN_BROWSER=1
POSITIONAL=()
while [[ $# -gt 0 ]]; do
case "$1" in
--landing) PROFILE="marketing_landing"; shift ;;
--full-stack) PROFILE="full_software"; shift ;; # backward compatible alias
--no-open) OPEN_BROWSER=0; shift ;;
--compose) export DEMO_BASE_URL="${DEMO_BASE_URL:-http://localhost:9080}"; shift ;;
-h|--help)
sed -n '1,25p' "$0" | tail -n +2
exit 0
;;
*) POSITIONAL+=("$1"); shift ;;
esac
done
IDEA="${POSITIONAL[*]:-}"
if [[ -z "${IDEA// }" ]]; then
IDEA="Landing page for AI-powered resume builder"
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "${SCRIPT_DIR}"
CNAME="${DEMO_CONTAINER_NAME:-ai-factory}"
if ! docker ps --format '{{.Names}}' | grep -qx "${CNAME}"; then
if docker ps -a --format '{{.Names}}' | grep -qx "${CNAME}"; then
echo "[demo] Starting container ${CNAME}..."
docker start "${CNAME}" >/dev/null
else
echo "[demo] No container '${CNAME}'. Launching via ./run.sh --no-build ..."
if [[ -x ./run.sh ]]; then
./run.sh --no-build || {
echo "[demo] run.sh failed — build first: ./run.sh"
exit 1
}
else
echo "[demo] ./run.sh not found or not executable."
exit 1
fi
fi
fi
pick_base() {
if [[ -n "${DEMO_BASE_URL:-}" ]]; then
echo "${DEMO_BASE_URL}"
return 0
fi
for cand in http://localhost:8080 http://localhost:9080; do
if curl -sf "${cand}/api/health" >/dev/null 2>&1; then
echo "${cand}"
return 0
fi
done
return 1
}
echo "[demo] Waiting for API health..."
BASE=""
for _ in $(seq 1 90); do
if BASE="$(pick_base || true)" && [[ -n "${BASE}" ]]; then
break
fi
sleep 2
done
if [[ -z "${BASE:-}" ]]; then
echo "[demo] Timeout: set DEMO_BASE_URL (e.g. http://localhost:8080)"
exit 1
fi
echo "[demo] Using API base: ${BASE}"
PASS="${DEMO_ADMIN_PASSWORD:-}"
if [[ -z "$PASS" && -f data/secrets/bootstrap_admin.txt ]]; then
PASS="$(tr -d '\n\r' < data/secrets/bootstrap_admin.txt)"
fi
if [[ -z "$PASS" ]]; then
echo "Set DEMO_ADMIN_PASSWORD or run docker compose up once to create data/secrets/bootstrap_admin.txt" >&2
exit 2
fi
login_json="$(curl -sS -X POST "${BASE}/api/admin/auth/login" \
-H 'Content-Type: application/json' \
-d "{\"username\":\"admin\",\"password\":\"${PASS}\"}")"
if command -v jq >/dev/null 2>&1; then
TOKEN="$(echo "${login_json}" | jq -r '.access_token // empty')"
else
TOKEN="$(python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('access_token') or '')" <<<"${login_json}")"
fi
if [[ -z "${TOKEN}" ]]; then
echo "[demo] Login failed (wrong password or 2FA enabled?). Response:"
echo "${login_json}" | head -c 400
echo ""
exit 1
fi
payload="$(python3 -c "
import json, sys
idea = sys.argv[1]
prof = sys.argv[2]
print(json.dumps({'idea': idea, 'delivery_profile': prof}))
" "${IDEA}" "${PROFILE}")"
create_json="$(curl -sS -X POST "${BASE}/api/admin/products/create" \
-H "Authorization: Bearer ${TOKEN}" \
-H 'Content-Type: application/json' \
-d "${payload}")"
if command -v jq >/dev/null 2>&1; then
PID="$(echo "${create_json}" | jq -r '.product_id // empty')"
else
PID="$(python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('product_id') or '')" <<<"${create_json}")"
fi
if [[ -z "${PID}" ]]; then
echo "[demo] Create product failed:"
echo "${create_json}" | head -c 600
echo ""
exit 1
fi
echo "[demo] Created ${PID} (profile=${PROFILE})"
echo "[demo] Idea: ${IDEA}"
TAB_URL="${BASE}/admin?tab=pipeline"
PROD_URL="${BASE}/product/${PID}"
if [[ "${OPEN_BROWSER}" == "1" ]]; then
echo "[demo] Opening Pipeline tab…"
case "$(uname -s)" in
Darwin) open "${TAB_URL}" ;;
MINGW*|CYGWIN*|MSYS*) start "${TAB_URL}" ;;
*) xdg-open "${TAB_URL}" 2>/dev/null || sensible-browser "${TAB_URL}" 2>/dev/null || true ;;
esac
fi
echo ""
echo " Pipeline (admin): ${TAB_URL}"
echo " Product page: ${PROD_URL}"
echo ""
echo "[demo] Full pipeline takes several minutes — watch tasks in Admin → Pipeline."