feat: complete Phase 1 foundation hardening + three-mode UI design doc

Phase 1a — Gradient Removal:
- Replaced all gradient-button/gradient-card with glass-button/path-option-card
- Removed banned gradient CSS classes

Phase 1b — Security Hardening:
- SecretsManager: AES-256-GCM encryption (core/security)
- electrs_status: credentials from env vars instead of hardcoded
- port_manager: RwLock proper error handling (no unwrap)
- Pinned all 11 :latest manifest images to specific versions
- parmanode converter: pinned inferred image versions

Phase 1c — Code Quality:
- Split rpc.rs (1795 lines) into 6 handler modules (auth, node, container, package, peers)
- Removed sideload code (UI, store, RPC client, 3 doc files)
- Fixed body background flash on logout/refresh
- Replaced 30 TypeScript `any` types with proper types
- Deleted HelloWorld.vue, removed TODO comments
- Added set -euo pipefail to all shell scripts
- Made deploy script verbose with timestamps and elapsed time

Also adds:
- CLAUDE.md project guide
- docs/three-mode-ui-design.md — design spec for Easy/Pro/Chat UI modes
- OnlineStatusPill component

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-04 05:23:42 +00:00
parent 62d6c13764
commit 486fc39249
58 changed files with 1902 additions and 2286 deletions

View File

@@ -1,4 +1,5 @@
#!/bin/bash
set -euo pipefail
# Quick script to check what's deployed on the target
echo "Checking deployed files on target..."

View File

@@ -1,4 +1,5 @@
#!/bin/bash
set -euo pipefail
# Check what's actually in the deployed frontend
TARGET_HOST="${ARCHIPELAGO_TARGET:-archipelago@192.168.1.228}"

View File

@@ -25,11 +25,14 @@ ARCHIPELAGO_PASSWORD="${ARCHIPELAGO_PASSWORD:-archipelago}"
# Force password auth when using sshpass (avoids "Permission denied" from SSH key mismatch)
SSH_OPTS="-o StrictHostKeyChecking=no -o PreferredAuthentications=password -o PubkeyAuthentication=no"
DEPLOY_START=$(date +%s)
timestamp() { echo "[$(date +%H:%M:%S)]"; }
echo "╔════════════════════════════════════════════════════════════════╗"
echo "║ Deploying to Archipelago Target ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo ""
echo "Target: $TARGET_HOST"
echo "$(timestamp) Target: $TARGET_HOST"
echo ""
# Parse arguments
@@ -70,7 +73,7 @@ if [ "$BOTH" = true ]; then
fi
# Sync code
echo "📦 Syncing code..."
echo "$(timestamp) 📦 Syncing code..."
sshpass -p "$ARCHIPELAGO_PASSWORD" rsync -avz --delete \
-e "ssh $SSH_OPTS" \
--exclude 'node_modules' \
@@ -89,33 +92,33 @@ fi
# Build on target
echo ""
echo "🔨 Building on target..."
echo "$(timestamp) 🔨 Building on target..."
# Frontend
echo " Building frontend..."
echo "$(timestamp) Building frontend (vue-tsc + vite)..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "cd $TARGET_DIR/neode-ui && npm install --silent && npm run build" 2>&1 | sed 's/^/ /'
# Backend (if Rust is installed)
if sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "source ~/.cargo/env 2>/dev/null && command -v cargo" >/dev/null 2>&1; then
echo " Building backend..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "source ~/.cargo/env && cd $TARGET_DIR/core && cargo build --release 2>&1" | tail -10 | sed 's/^/ /'
echo "$(timestamp) Building backend (Rust release — this takes 1-2 min)..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "source ~/.cargo/env && cd $TARGET_DIR/core && cargo build --release 2>&1" | sed 's/^/ /'
else
echo " ⚠️ Rust not installed on target, skipping backend build"
fi
if [ "$LIVE" = true ]; then
echo ""
echo "🚀 Deploying to live system..."
echo "$(timestamp) 🚀 Deploying to live system..."
# Deploy backend (check if binary exists)
if sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "[ -f $TARGET_DIR/core/target/release/archipelago ]" 2>/dev/null; then
echo " Deploying backend binary..."
echo "$(timestamp) Deploying backend binary..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo systemctl stop archipelago"
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo cp $TARGET_DIR/core/target/release/archipelago /usr/local/bin/"
fi
# Deploy frontend
echo " Deploying frontend..."
echo "$(timestamp) Deploying frontend..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo rm -rf /opt/archipelago/web-ui/*"
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo cp -r $TARGET_DIR/web/dist/neode-ui/* /opt/archipelago/web-ui/"
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo chown -R 1000:1000 /opt/archipelago/web-ui"
@@ -157,15 +160,15 @@ if [ "$LIVE" = true ]; then
fi
# Restart services
echo " Restarting services..."
echo "$(timestamp) Restarting services..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo systemctl start archipelago && sudo systemctl restart nginx"
# Set up HTTPS for PWA installability (browsers require secure context)
echo " Setting up HTTPS for PWA install..."
echo "$(timestamp) Setting up HTTPS for PWA install..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "sudo bash $TARGET_DIR/scripts/setup-https-dev.sh" 2>&1 | sed 's/^/ /' || true
# Rebuild and recreate LND UI container (port 8081 so Launch from UI and http://host:8081 both work)
echo " Rebuilding LND UI..."
echo "$(timestamp) Rebuilding LND UI..."
if sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "cd $TARGET_DIR/docker/lnd-ui && (command -v podman >/dev/null 2>&1 && sudo podman build --no-cache -t lnd-ui:latest . || sudo docker build --no-cache -t lnd-ui:latest .)" 2>&1 | tail -12 | sed 's/^/ /'; then
echo " Recreating LND UI container (port 8081)..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" '
@@ -179,7 +182,7 @@ if [ "$LIVE" = true ]; then
fi
# Rebuild and recreate Electrs UI container (port 50002)
echo " Rebuilding Electrs UI..."
echo "$(timestamp) Rebuilding Electrs UI..."
if sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "cd $TARGET_DIR/docker/electrs-ui && (command -v podman >/dev/null 2>&1 && sudo podman build --no-cache -t electrs-ui:latest . || sudo docker build --no-cache -t electrs-ui:latest .)" 2>&1 | tail -12 | sed 's/^/ /'; then
echo " Recreating Electrs UI container (port 50002, host network)..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" '
@@ -194,7 +197,7 @@ if [ "$LIVE" = true ]; then
# Bitcoin Knots: required for Mempool, Electrs, BTCPay, Fedimint
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
echo " Ensuring Bitcoin Knots (required for Electrs/Mempool)..."
echo "$(timestamp) Ensuring Bitcoin Knots..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
DOCKER=podman
command -v podman >/dev/null 2>&1 || DOCKER=docker
@@ -218,7 +221,7 @@ if [ "$LIVE" = true ]; then
" 2>&1 | sed 's/^/ /' || true
# Fix Mempool: clean duplicates, ensure full stack - mysql, backend (8999), frontend (4080)
echo " Fixing Mempool stack (host=$TARGET_IP)..."
echo "$(timestamp) Fixing Mempool stack..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
DOCKER=podman
command -v podman >/dev/null 2>&1 || DOCKER=docker
@@ -322,7 +325,7 @@ if [ "$LIVE" = true ]; then
" 2>&1 | sed 's/^/ /' || true
# Fix BTCPay Server: requires PostgreSQL + NBXplorer (BTCPay needs NBXplorer for block indexing)
echo " Fixing BTCPay Server stack..."
echo "$(timestamp) Fixing BTCPay Server stack..."
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
DOCKER=podman
@@ -397,7 +400,7 @@ if [ "$LIVE" = true ]; then
" 2>&1 | sed 's/^/ /' || true
# Ensure Immich stack (postgres + redis + server) - creates if missing
echo " Ensuring Immich stack (port 2283)..."
echo "$(timestamp) Ensuring Immich stack..."
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
DOCKER=podman
command -v podman >/dev/null 2>&1 || DOCKER=docker
@@ -439,7 +442,7 @@ if [ "$LIVE" = true ]; then
" 2>&1 | sed 's/^/ /' || true
# Tor: global hidden services - each service gets its own .onion address
echo " Setting up Tor (hidden services for each app)..."
echo "$(timestamp) Setting up Tor..."
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" "
DOCKER=podman
@@ -505,7 +508,7 @@ if [ "$LIVE" = true ]; then
" 2>&1 | sed 's/^/ /' || true
# Recreate Fedimint with FM_API_URL for Guardian UI (fixes "Api URL must be configured")
echo " Fixing Fedimint API URL..."
echo "$(timestamp) Fixing Fedimint API URL..."
TARGET_IP="$(echo "$TARGET_HOST" | cut -d@ -f2)"
TIMEOUT_CMD=""
command -v timeout >/dev/null 2>&1 && TIMEOUT_CMD="timeout 90"
@@ -535,8 +538,10 @@ if [ "$LIVE" = true ]; then
done
" 2>&1 | sed 's/^/ /') || echo " (Fedimint fix timed out or skipped - run manually if needed)"
DEPLOY_END=$(date +%s)
DEPLOY_ELAPSED=$((DEPLOY_END - DEPLOY_START))
echo ""
echo "✅ Deployed to live system!"
echo "$(timestamp) ✅ Deployed to live system! (${DEPLOY_ELAPSED}s total)"
echo " Backend: $(sshpass -p "$ARCHIPELAGO_PASSWORD" ssh $SSH_OPTS "$TARGET_HOST" 'sudo systemctl is-active archipelago')"
echo " Web UI: http://$(echo $TARGET_HOST | cut -d@ -f2)"
echo " PWA install: https://$(echo $TARGET_HOST | cut -d@ -f2) (use HTTPS, accept cert once, then Install app)"

View File

@@ -1,4 +1,5 @@
#!/bin/bash
set -euo pipefail
# Archipelago Development Server Starter
# Pure Archipelago implementation - NO StartOS

View File

@@ -1,4 +1,5 @@
#!/bin/bash
set -euo pipefail
# Quick dev script - just starts the mock backend for UI development
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

View File

@@ -1,4 +1,5 @@
#!/bin/bash
set -euo pipefail
# Test if the new backend binary has the bundled-app methods
TARGET_HOST="${ARCHIPELAGO_TARGET:-archipelago@192.168.1.228}"

View File

@@ -1,4 +1,5 @@
#!/bin/bash
set -euo pipefail
# Verify the deployment is working correctly
TARGET_HOST="${ARCHIPELAGO_TARGET:-archipelago@192.168.1.228}"