The UI was previously a Vue 3 SPA served via a Vite dev server on :1420.
This had two problems:
- Building from source required Node, npm, and the Tauri CLI
- Running required starting a Vite dev server alongside the binary
Replace with a single self-contained dist/index.html using vanilla JS
and the Tauri 2 withGlobalTauri IPC global. No build step, no npm, no
dev server — the binary loads the static file directly.
Changes:
- dist/index.html: full Robin UI (chat, events, debug tabs) in ~750 LOC
- Chat tab: streaming LLM responses via robin:chat-token events
- Events tab: live matched system events with severity badges
- Debug tab: migration config, Ollama status probe, notif level picker
- Onboarding form shown on first run (calls complete_onboarding IPC)
- All user/LLM text via textContent/DOM construction, no innerHTML
- Markdown renderer (fenced code, inline code) built from DOM nodes
- tauri.conf.json: add withGlobalTauri: true, remove devUrl and Node hooks
- tauri.conf.json: update CSP to allow inline scripts (desktop app)
- manage.sh: remove Vite dev server auto-start and kill logic
- manage.sh: build/dev now use cargo directly, add bundle command for
full .deb/.rpm/.AppImage (still requires Tauri CLI)
- .gitignore: track dist/index.html, only ignore dist/assets/ (Vite output)
280 lines
8.1 KiB
Bash
Executable file
280 lines
8.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Robin — manage.sh
|
|
# Usage: ./manage.sh <command>
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
APP_NAME="robin"
|
|
RELEASE_BIN="$SCRIPT_DIR/src-tauri/target/release/$APP_NAME"
|
|
DEBUG_BIN="$SCRIPT_DIR/src-tauri/target/debug/$APP_NAME"
|
|
ICON="$SCRIPT_DIR/src-tauri/icons/128x128.png"
|
|
LOG_FILE="${XDG_DATA_HOME:-$HOME/.local/share}/tech.circuitforge.robin/logs/Robin.log"
|
|
|
|
cmd="${1:-help}"
|
|
|
|
# ── Helpers ───────────────────────────────────────────────────────────────────
|
|
|
|
_find_binary() {
|
|
if [[ -f "$RELEASE_BIN" ]]; then
|
|
echo "$RELEASE_BIN"
|
|
elif [[ -f "$DEBUG_BIN" ]]; then
|
|
echo "$DEBUG_BIN"
|
|
else
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
_require_binary() {
|
|
local bin
|
|
bin="$(_find_binary)"
|
|
if [[ -z "$bin" ]]; then
|
|
echo "Robin binary not found. Run one of:"
|
|
echo " ./manage.sh build (release, requires Node + Tauri CLI)"
|
|
echo " ./manage.sh build-debug (debug, requires Rust only)"
|
|
exit 1
|
|
fi
|
|
echo "$bin"
|
|
}
|
|
|
|
# ── Commands ──────────────────────────────────────────────────────────────────
|
|
|
|
case "$cmd" in
|
|
|
|
run)
|
|
# Run the binary in the foreground (logs to terminal).
|
|
# Use this for manual testing; Ctrl+C to quit.
|
|
bin="$(_require_binary)"
|
|
echo "Starting Robin ($bin)..."
|
|
export DISPLAY="${DISPLAY:-:0}"
|
|
export RUST_LOG="${RUST_LOG:-robin_lib=info,warn}"
|
|
exec "$bin"
|
|
;;
|
|
|
|
start)
|
|
# Start Robin in the background (daemonised via nohup).
|
|
# No dev server needed — the webview loads dist/index.html directly.
|
|
if pgrep -x "$APP_NAME" > /dev/null 2>&1; then
|
|
echo "Robin is already running (PID $(pgrep -x "$APP_NAME"))"
|
|
exit 0
|
|
fi
|
|
bin="$(_require_binary)"
|
|
export DISPLAY="${DISPLAY:-:0}"
|
|
export RUST_LOG="${RUST_LOG:-robin_lib=info,warn}"
|
|
mkdir -p "$(dirname "$LOG_FILE")"
|
|
nohup "$bin" >> "$LOG_FILE" 2>&1 &
|
|
echo "Robin started (PID $!). Logs: $LOG_FILE"
|
|
;;
|
|
|
|
stop)
|
|
if pgrep -x "$APP_NAME" > /dev/null 2>&1; then
|
|
pkill -x "$APP_NAME"
|
|
echo "Robin stopped."
|
|
else
|
|
echo "Robin is not running."
|
|
fi
|
|
;;
|
|
|
|
restart)
|
|
"$0" stop || true
|
|
sleep 1
|
|
"$0" start
|
|
;;
|
|
|
|
status)
|
|
if pgrep -x "$APP_NAME" > /dev/null 2>&1; then
|
|
echo "Robin is running (PID $(pgrep -x "$APP_NAME"))"
|
|
else
|
|
echo "Robin is not running."
|
|
fi
|
|
;;
|
|
|
|
logs)
|
|
if [[ -f "$LOG_FILE" ]]; then
|
|
tail -f "$LOG_FILE"
|
|
else
|
|
echo "No log file yet at $LOG_FILE"
|
|
echo "Start Robin first: ./manage.sh start"
|
|
fi
|
|
;;
|
|
|
|
dev)
|
|
# Dev mode: build debug binary and run it directly.
|
|
# The webview loads dist/index.html from the build artefact path —
|
|
# no npm or Vite server required.
|
|
echo "Building and running Robin in dev mode..."
|
|
cargo build --manifest-path "$SCRIPT_DIR/src-tauri/Cargo.toml"
|
|
export DISPLAY="${DISPLAY:-:0}"
|
|
export RUST_LOG="${RUST_LOG:-robin_lib=debug,warn}"
|
|
exec "$DEBUG_BIN"
|
|
;;
|
|
|
|
build)
|
|
echo "Building Robin release binary..."
|
|
cargo build --release --manifest-path "$SCRIPT_DIR/src-tauri/Cargo.toml"
|
|
echo "Binary: $RELEASE_BIN"
|
|
;;
|
|
|
|
bundle)
|
|
# Full release bundle (.deb/.rpm/.AppImage) — requires Tauri CLI (npm install -g @tauri-apps/cli)
|
|
echo "Building Robin release bundle (deb/rpm/AppImage)..."
|
|
cd "$SCRIPT_DIR"
|
|
cargo tauri build
|
|
;;
|
|
|
|
build-debug)
|
|
echo "Building Robin debug binary (Rust only, no Node needed)..."
|
|
cargo build --manifest-path "$SCRIPT_DIR/src-tauri/Cargo.toml"
|
|
echo "Binary: $DEBUG_BIN"
|
|
;;
|
|
|
|
test)
|
|
echo "Running Rust tests..."
|
|
cargo test --manifest-path "$SCRIPT_DIR/src-tauri/Cargo.toml" --lib
|
|
;;
|
|
|
|
install-deps)
|
|
echo "Installing system dependencies (Debian/Ubuntu/Mint)..."
|
|
sudo apt-get install -y \
|
|
libwebkit2gtk-4.1-dev \
|
|
libayatana-appindicator3-dev \
|
|
librsvg2-dev \
|
|
libgtk-3-dev \
|
|
libssl-dev \
|
|
pkg-config
|
|
echo "Installing Rust dependencies..."
|
|
cargo fetch --manifest-path "$SCRIPT_DIR/src-tauri/Cargo.toml"
|
|
;;
|
|
|
|
install-deps-arch)
|
|
echo "Installing system dependencies (Arch/Manjaro/CachyOS)..."
|
|
paru -S --needed \
|
|
webkit2gtk-4.1 \
|
|
libayatana-appindicator \
|
|
librsvg \
|
|
gtk3 \
|
|
openssl \
|
|
pkg-config
|
|
cargo fetch --manifest-path "$SCRIPT_DIR/src-tauri/Cargo.toml"
|
|
;;
|
|
|
|
desktop-install)
|
|
# Install .desktop entry so Robin appears in the system app menu.
|
|
bin="$(_require_binary)"
|
|
APPS_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/applications"
|
|
mkdir -p "$APPS_DIR"
|
|
cat > "$APPS_DIR/robin.desktop" <<EOF
|
|
[Desktop Entry]
|
|
Version=1.0
|
|
Type=Application
|
|
Name=Robin
|
|
GenericName=Linux Migration Assistant
|
|
Comment=Helps you find your feet on Linux
|
|
Exec=$bin
|
|
Icon=$ICON
|
|
Categories=Utility;System;
|
|
StartupNotify=false
|
|
StartupWMClass=Robin
|
|
Keywords=linux;migration;help;assistant;
|
|
EOF
|
|
update-desktop-database "$APPS_DIR" 2>/dev/null || true
|
|
echo "Robin added to application menu."
|
|
echo "Entry: $APPS_DIR/robin.desktop"
|
|
;;
|
|
|
|
desktop-remove)
|
|
DESKTOP="${XDG_DATA_HOME:-$HOME/.local/share}/applications/robin.desktop"
|
|
if [[ -f "$DESKTOP" ]]; then
|
|
rm "$DESKTOP"
|
|
update-desktop-database "$(dirname "$DESKTOP")" 2>/dev/null || true
|
|
echo "Robin removed from application menu."
|
|
else
|
|
echo "No desktop entry found at $DESKTOP"
|
|
fi
|
|
;;
|
|
|
|
autostart-enable)
|
|
# Start Robin automatically when the desktop session begins.
|
|
bin="$(_require_binary)"
|
|
AUTOSTART_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/autostart"
|
|
mkdir -p "$AUTOSTART_DIR"
|
|
cat > "$AUTOSTART_DIR/robin.desktop" <<EOF
|
|
[Desktop Entry]
|
|
Version=1.0
|
|
Type=Application
|
|
Name=Robin
|
|
Comment=Helps you find your feet on Linux
|
|
Exec=$bin
|
|
Icon=$ICON
|
|
StartupNotify=false
|
|
X-GNOME-Autostart-enabled=true
|
|
Hidden=false
|
|
NoDisplay=false
|
|
EOF
|
|
echo "Robin will start automatically at login."
|
|
echo "Entry: $AUTOSTART_DIR/robin.desktop"
|
|
;;
|
|
|
|
autostart-disable)
|
|
AUTOSTART="${XDG_CONFIG_HOME:-$HOME/.config}/autostart/robin.desktop"
|
|
if [[ -f "$AUTOSTART" ]]; then
|
|
rm "$AUTOSTART"
|
|
echo "Robin autostart disabled."
|
|
else
|
|
echo "No autostart entry found at $AUTOSTART"
|
|
fi
|
|
;;
|
|
|
|
install)
|
|
# Full install: build-debug + desktop-install + autostart-enable
|
|
echo "=== Robin install ==="
|
|
"$0" build-debug
|
|
"$0" desktop-install
|
|
"$0" autostart-enable
|
|
echo ""
|
|
echo "Robin installed. It will start at next login."
|
|
echo "Start it now: ./manage.sh start"
|
|
;;
|
|
|
|
uninstall)
|
|
"$0" stop || true
|
|
"$0" desktop-remove || true
|
|
"$0" autostart-disable || true
|
|
echo "Robin uninstalled."
|
|
;;
|
|
|
|
help|*)
|
|
cat <<'EOF'
|
|
Robin — Linux migration companion
|
|
Usage: ./manage.sh <command>
|
|
|
|
Running:
|
|
run Run in foreground (logs to terminal, Ctrl+C to quit)
|
|
start Start in background (no dev server needed)
|
|
stop Stop background instance
|
|
restart Stop then start
|
|
status Show whether Robin is running
|
|
logs Tail the Robin log file
|
|
|
|
Building:
|
|
build-debug Build debug binary (Rust only, no Node/npm needed)
|
|
build Build release binary (Rust only)
|
|
bundle Build release bundle (.deb/.rpm/.AppImage) — requires Tauri CLI
|
|
dev Build debug binary and run it immediately
|
|
test Run Rust unit tests
|
|
|
|
Installation:
|
|
install build-debug + desktop-install + autostart-enable
|
|
uninstall Remove desktop entry, autostart, and stop Robin
|
|
desktop-install Add Robin to the system application menu
|
|
desktop-remove Remove Robin from the application menu
|
|
autostart-enable Start Robin automatically at login
|
|
autostart-disable Stop Robin from starting at login
|
|
|
|
Dependencies:
|
|
install-deps Install system deps (Debian/Ubuntu/Mint)
|
|
install-deps-arch Install system deps (Arch/Manjaro/CachyOS)
|
|
|
|
Note: No Node.js or npm required. The UI is a static HTML file bundled with the binary.
|
|
EOF
|
|
;;
|
|
esac
|