#!/bin/bash set -e TTYD_VERSION="${TTYD_VERSION:-1.7.7}" SKILLS_DIR="${SKILLS_DIR:-/skills}" TTYD_PORT="${TTYD_PORT:-7681}" TTYD_DOMAIN="${TTYD_DOMAIN:-}" # Idempotent ttyd installation install_ttyd() { if command -v ttyd &>/dev/null; then echo "ttyd already installed: $(ttyd --version)" return 0 fi echo "Installing ttyd v${TTYD_VERSION}..." # Detect architecture local arch case "$(uname -m)" in x86_64) arch="x86_64" ;; aarch64) arch="aarch64" ;; armv7l) arch="armhf" ;; *) echo "Unsupported architecture: $(uname -m)" exit 1 ;; esac # Download prebuilt binary local url="https://github.com/tsl0922/ttyd/releases/download/${TTYD_VERSION}/ttyd.${arch}" curl -sSL "$url" -o /usr/local/bin/ttyd chmod +x /usr/local/bin/ttyd echo "ttyd installed: $(ttyd --version)" } # Configure Caddy if present configure_caddy() { local caddy_dir="$SKILLS_DIR/caddy" if [ ! -d "$caddy_dir" ]; then echo "Caddy not found - ttyd will run standalone on port $TTYD_PORT" return 0 fi echo "Caddy detected - configuring reverse proxy..." # Create snippets directory for modular config local snippets_dir="$caddy_dir/snippets.d" mkdir -p "$snippets_dir" # Generate ttyd snippet local snippet="$snippets_dir/ttyd.caddy" if [ -n "$TTYD_DOMAIN" ]; then # Domain-based routing cat > "$snippet" << EOF # Auto-generated by ttyd skill $TTYD_DOMAIN { reverse_proxy localhost:$TTYD_PORT } EOF echo "Caddy config: $TTYD_DOMAIN -> localhost:$TTYD_PORT" else # Path-based routing (fallback) cat > "$snippet" << EOF # Auto-generated by ttyd skill # Add to your site block: # handle /terminal/* { # uri strip_prefix /terminal # reverse_proxy localhost:$TTYD_PORT # } EOF echo "Caddy snippet created: $snippet (manual path-based config)" fi } install_ttyd configure_caddy