Ctrl K
ComunidadGuías…

entrypoint-skyvernui.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/bin/bash

set -euo pipefail

# Escape a VITE value for JS string contents, then for a sed replacement.
escape_js_sed() {
    if [[ "$1" == *$'\n'* ]]; then
        echo "ERROR: escape_js_sed called with multi-line value; refusing to corrupt the bundle" >&2
        exit 1
    fi
    VITE_VALUE="$1" node -e '
        const value = JSON.stringify(process.env.VITE_VALUE).slice(1, -1)
            .replace(/\x60/g, String.fromCharCode(92, 96))
            .replace(/\$\{/g, String.fromCharCode(92, 36, 123))
            .replace(/\x27/g, "\\x27")
            .replace(/\u2028/g, "\\u2028")
            .replace(/\u2029/g, "\\u2029");
        process.stdout.write(value.replace(/[\\&|\/]/g, "\\$&"));
    '
}

# Default values for environment variables
VITE_API_BASE_URL="${VITE_API_BASE_URL:-http://localhost:8000/api/v1}"
VITE_WSS_BASE_URL="${VITE_WSS_BASE_URL:-ws://localhost:8000/api/v1}"
VITE_ARTIFACT_API_BASE_URL="${VITE_ARTIFACT_API_BASE_URL:-http://localhost:9090}"
VITE_BROWSER_STREAMING_MODE="${VITE_BROWSER_STREAMING_MODE:-vnc}"
VITE_ENABLE_LOG_ARTIFACTS="${VITE_ENABLE_LOG_ARTIFACTS:-false}"
VITE_ENABLE_CODE_BLOCK="${VITE_ENABLE_CODE_BLOCK:-false}"
VITE_ENVIRONMENT="${VITE_ENVIRONMENT:-local}"
VITE_API_PATH_PREFIX="${VITE_API_PATH_PREFIX:-}"
VITE_ENABLE_2FA_NOTIFICATIONS="${VITE_ENABLE_2FA_NOTIFICATIONS:-false}"
VITE_CLERK_PUBLISHABLE_KEY="${VITE_CLERK_PUBLISHABLE_KEY:-}"
VITE_PUBLIC_POSTHOG_HOST="${VITE_PUBLIC_POSTHOG_HOST:-}"
VITE_PUBLIC_POSTHOG_KEY="${VITE_PUBLIC_POSTHOG_KEY:-}"

# Priority for the server-side organization key:
# 1. SKYVERN_API_KEY environment variable
# 2. VITE_SKYVERN_API_KEY environment variable
# 3. Generated credentials file mounted by the open-source deployment
# 4. Fallback to .streamlit/secrets.toml (only available in self-hosted
#    docker-compose deployments where the file is volume-mounted; not
#    present in K8s deployments)
SKYVERN_API_KEY="${SKYVERN_API_KEY:-}"
VITE_SKYVERN_API_KEY="${VITE_SKYVERN_API_KEY:-}"
SKYVERN_CREDENTIALS_FILE="${SKYVERN_CREDENTIALS_FILE:-/app/.skyvern/credentials.toml}"
if [ -n "$SKYVERN_API_KEY" ]; then
    SKYVERN_API_KEY="${SKYVERN_API_KEY#"${SKYVERN_API_KEY%%[![:space:]]*}"}"
    SKYVERN_API_KEY="${SKYVERN_API_KEY%"${SKYVERN_API_KEY##*[![:space:]]}"}"
    echo "Using SKYVERN_API_KEY from environment variable"
elif [ -n "$VITE_SKYVERN_API_KEY" ]; then
    VITE_SKYVERN_API_KEY="${VITE_SKYVERN_API_KEY#"${VITE_SKYVERN_API_KEY%%[![:space:]]*}"}"
    VITE_SKYVERN_API_KEY="${VITE_SKYVERN_API_KEY%"${VITE_SKYVERN_API_KEY##*[![:space:]]}"}"
    SKYVERN_API_KEY="$VITE_SKYVERN_API_KEY"
    echo "Using VITE_SKYVERN_API_KEY from environment variable"
else
    SKYVERN_API_KEY=$(sed -n 's/.*cred[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' "$SKYVERN_CREDENTIALS_FILE" 2>/dev/null || echo "")
    if [ -n "$SKYVERN_API_KEY" ]; then
        echo "Using SKYVERN_API_KEY from $SKYVERN_CREDENTIALS_FILE"
    else
        SKYVERN_API_KEY=$(sed -n 's/.*cred[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' .streamlit/secrets.toml 2>/dev/null || echo "")
        if [ -n "$SKYVERN_API_KEY" ]; then
            echo "Using SKYVERN_API_KEY from .streamlit/secrets.toml"
        else
            echo "WARNING: No organization key found in environment, $SKYVERN_CREDENTIALS_FILE, or .streamlit/secrets.toml"
        fi
    fi
fi
export SKYVERN_API_KEY
export VITE_API_BASE_URL

echo "Injecting runtime environment variables into pre-built assets..."

if [ -d /app/dist.template ]; then
    rm -rf /app/dist
    cp -r /app/dist.template /app/dist
fi

# Escape all values for safe use in sed replacement patterns
ESC_API_BASE_URL=$(escape_js_sed "$VITE_API_BASE_URL")
ESC_WSS_BASE_URL=$(escape_js_sed "$VITE_WSS_BASE_URL")
ESC_ARTIFACT_API_BASE_URL=$(escape_js_sed "$VITE_ARTIFACT_API_BASE_URL")
ESC_BROWSER_STREAMING_MODE=$(escape_js_sed "$VITE_BROWSER_STREAMING_MODE")
ESC_ENABLE_LOG_ARTIFACTS=$(escape_js_sed "$VITE_ENABLE_LOG_ARTIFACTS")
ESC_ENABLE_CODE_BLOCK=$(escape_js_sed "$VITE_ENABLE_CODE_BLOCK")
ESC_ENVIRONMENT=$(escape_js_sed "$VITE_ENVIRONMENT")
ESC_API_PATH_PREFIX=$(escape_js_sed "$VITE_API_PATH_PREFIX")
ESC_ENABLE_2FA_NOTIFICATIONS=$(escape_js_sed "$VITE_ENABLE_2FA_NOTIFICATIONS")
ESC_CLERK_PUBLISHABLE_KEY=$(escape_js_sed "$VITE_CLERK_PUBLISHABLE_KEY")
ESC_PUBLIC_POSTHOG_HOST=$(escape_js_sed "$VITE_PUBLIC_POSTHOG_HOST")
ESC_PUBLIC_POSTHOG_KEY=$(escape_js_sed "$VITE_PUBLIC_POSTHOG_KEY")

# Replace placeholder strings in pre-built JS and HTML files with actual runtime values
find /app/dist \( -name "*.js" -o -name "*.html" \) -exec sed -i \
    -e "s|__VITE_API_BASE_URL_PLACEHOLDER__-__|${ESC_API_BASE_URL}|g" \
    -e "s|__VITE_API_BASE_URL_PLACEHOLDER__|${ESC_API_BASE_URL}|g" \
    -e "s|__VITE_WSS_BASE_URL_PLACEHOLDER__|${ESC_WSS_BASE_URL}|g" \
    -e "s|__VITE_ARTIFACT_API_BASE_URL_PLACEHOLDER__|${ESC_ARTIFACT_API_BASE_URL}|g" \
    -e "s|__VITE_BROWSER_STREAMING_MODE_PLACEHOLDER__|${ESC_BROWSER_STREAMING_MODE}|g" \
    -e "s|__VITE_ENABLE_LOG_ARTIFACTS_PLACEHOLDER__|${ESC_ENABLE_LOG_ARTIFACTS}|g" \
    -e "s|__VITE_ENABLE_CODE_BLOCK_PLACEHOLDER__|${ESC_ENABLE_CODE_BLOCK}|g" \
    -e "s|__VITE_ENVIRONMENT_PLACEHOLDER__|${ESC_ENVIRONMENT}|g" \
    -e "s|__VITE_API_PATH_PREFIX_PLACEHOLDER__|${ESC_API_PATH_PREFIX}|g" \
    -e "s|__VITE_ENABLE_2FA_NOTIFICATIONS_PLACEHOLDER__|${ESC_ENABLE_2FA_NOTIFICATIONS}|g" \
    -e "s|__VITE_CLERK_PUBLISHABLE_KEY_PLACEHOLDER__|${ESC_CLERK_PUBLISHABLE_KEY}|g" \
    -e "s|__VITE_PUBLIC_POSTHOG_HOST_PLACEHOLDER__|${ESC_PUBLIC_POSTHOG_HOST}|g" \
    -e "s|__VITE_PUBLIC_POSTHOG_KEY_PLACEHOLDER__|${ESC_PUBLIC_POSTHOG_KEY}|g" \
    {} +

# Sanity check: ensure ALL placeholders were actually replaced.
# If Vite ever splits/mangles a placeholder string, sed will silently
# succeed while leaving the placeholder in the bundle — catch that here.
# Scoped to *.js and *.html (the files sed modifies above) so unmodified
# sourcemaps don't trigger false positives.
if grep -rqE --include='*.js' --include='*.html' \
    '__VITE_[A-Z0-9_]+_PLACEHOLDER__' /app/dist/; then
    echo "ERROR: Placeholder replacement incomplete in dist/. Unreplaced placeholders:" >&2
    grep -rhoE --include='*.js' --include='*.html' \
        '__VITE_[A-Z0-9_]+_PLACEHOLDER__' /app/dist/ \
        | sort -u | sed 's/^/  /' >&2
    exit 1
fi

echo "Starting servers..."

# Ensure both servers are cleaned up if either one exits unexpectedly
trap 'kill $(jobs -p) 2>/dev/null; wait' EXIT

# Start the local server (serves pre-built static assets) and artifact server
node localServer.js &
node artifactServer.js &

# Exit as soon as either server terminates so the container restarts promptly.
# `wait -n` requires bash 4.3+; the base image (node:24.14-slim / Debian 12)
# ships bash 5.2 — revisit if the base image is ever swapped for one with an
# older bash (e.g. alpine's ash, which doesn't support `wait -n` at all).
wait -n
exit $?