Files
fidoca/install.sh
2026-09-23 00:50:44 +02:00

175 lines
5.9 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# install.sh — install Fido into ~/.fido and wire it into your shell.
#
# Usage:
# ./install.sh # install (or re-install) into $FIDO_HOME (default ~/.fido)
# FIDO_HOME=/opt/fido ./install.sh
# LLMORBITER_SRC=/path/to/llmorbiter ./install.sh
# ./install.sh --uninstall # remove the install and the PATH entry
# ./install.sh --help
#
# Environment:
# FIDO_HOME install directory (default: ~/.fido)
# LLMORBITER_SRC path to the llmorbiter checkout (default: sibling of this repo)
# BASHRC shell rc file to edit (default: ~/.bashrc)
# FIDO_SKIP_DEPS=1 skip `npm install` (useful for testing)
#
# What it does:
# 1. Copies the app into $FIDO_HOME/app
# 2. Bundles the llmorbiter dep $FIDO_HOME/llmorbiter (required by "file:../llmorbiter")
# 3. Copies your config to $FIDO_HOME/.env
# 4. Installs the launcher at $FIDO_HOME/bin/fido
# 5. Runs `npm install` for the app and for llmorbiter
# 6. Adds $FIDO_HOME/bin to PATH in ~/.bashrc
#
# All undo/suspend state lives under $FIDO_HOME/state/<workspace>/.
set -euo pipefail
FIDO_HOME="${FIDO_HOME:-$HOME/.fido}"
# Directory of this script = the repo root.
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# llmorbiter is a sibling checkout by default; override with LLMORBITER_SRC.
LLMORBITER_SRC="${LLMORBITER_SRC:-$SRC_DIR/../llmorbiter}"
BASHRC="${BASHRC:-$HOME/.bashrc}"
PATH_MARKER_BEGIN="# >>> fido >>>"
PATH_MARKER_END="# <<< fido <<<"
info() { printf '\033[36m▸\033[0m %s\n' "$*"; }
warn() { printf '\033[33m!\033[0m %s\n' "$*" >&2; }
die() { printf '\033[31m✖\033[0m %s\n' "$*" >&2; exit 1; }
usage() {
sed -n '2,30p' "$0" | sed 's/^# \{0,1\}//'
}
# Copy a source tree, skipping build/state noise and dotfile cruft.
copy_tree() {
local src="$1" dst="$2"
mkdir -p "$dst"
if command -v rsync >/dev/null 2>&1; then
rsync -a --delete \
--exclude 'node_modules' --exclude '.git' \
--exclude '.env' --exclude '.fido-*' \
"$src/" "$dst/"
else
local tmp
tmp="$(mktemp -d)"
tar -C "$src" \
--exclude=./node_modules --exclude=./.git \
--exclude=./.env --exclude='./.fido-*' \
-cf - . | tar -C "$tmp" -xf -
rm -rf "$dst"
mkdir -p "$dst"
cp -a "$tmp/." "$dst/"
rm -rf "$tmp"
fi
}
add_to_path() {
if [ -f "$BASHRC" ] && grep -qF "$PATH_MARKER_BEGIN" "$BASHRC"; then
info "PATH entry already present in $BASHRC"
return
fi
{
printf '\n%s\n' "$PATH_MARKER_BEGIN"
printf '# Added by the Fido installer — makes the "fido" launcher available.\n'
printf 'export PATH="%s/bin:$PATH"\n' "$FIDO_HOME"
printf '%s\n' "$PATH_MARKER_END"
} >> "$BASHRC"
info "Added $FIDO_HOME/bin to PATH in $BASHRC"
}
remove_from_path() {
[ -f "$BASHRC" ] || return
if grep -qF "$PATH_MARKER_BEGIN" "$BASHRC"; then
sed -i "/^# >>> fido >>>$/,/^# <<< fido <<<$/d" "$BASHRC"
info "Removed PATH entry from $BASHRC"
fi
}
do_install() {
command -v node >/dev/null 2>&1 || die "node not found in PATH — install Node.js first."
command -v npm >/dev/null 2>&1 || die "npm not found in PATH."
[ -f "$SRC_DIR/src/fido.js" ] || die "src/fido.js not found — run this script from the Fido repo root."
[ -f "$SRC_DIR/bin/fido" ] || die "bin/fido not found — is this a complete checkout?"
[ -d "$LLMORBITER_SRC" ] || die "llmorbiter dependency not found at: $LLMORBITER_SRC
Set LLMORBITER_SRC=/path/to/llmorbiter and re-run."
info "Installing Fido into $FIDO_HOME"
mkdir -p "$FIDO_HOME/bin" "$FIDO_HOME/state"
info "Copying app -> $FIDO_HOME/app"
copy_tree "$SRC_DIR" "$FIDO_HOME/app"
info "Bundling llmorbiter -> $FIDO_HOME/llmorbiter"
copy_tree "$LLMORBITER_SRC" "$FIDO_HOME/llmorbiter"
# Config: never clobber an existing install's .env (users edit it in place).
if [ -f "$FIDO_HOME/.env" ]; then
info "Keeping existing $FIDO_HOME/.env"
elif [ -f "$SRC_DIR/.env" ]; then
cp "$SRC_DIR/.env" "$FIDO_HOME/.env"
info "Copied .env -> $FIDO_HOME/.env"
else
cp "$SRC_DIR/.env.example" "$FIDO_HOME/.env"
warn "No .env found — wrote $FIDO_HOME/.env from .env.example."
warn "Edit it and set OPENROUTER_API_KEY before running fido."
fi
info "Installing launcher -> $FIDO_HOME/bin/fido"
cp "$SRC_DIR/bin/fido" "$FIDO_HOME/bin/fido"
chmod +x "$FIDO_HOME/bin/fido"
if [ "${FIDO_SKIP_DEPS:-0}" = "1" ]; then
warn "FIDO_SKIP_DEPS=1 — skipping npm install."
else
info "Installing dependencies (npm install) — this may take a moment…"
( cd "$FIDO_HOME/llmorbiter" && npm install --no-audit --no-fund )
( cd "$FIDO_HOME/app" && npm install --no-audit --no-fund )
fi
add_to_path
cat <<EOF
✅ Fido installed.
Home: $FIDO_HOME
Launcher: $FIDO_HOME/bin/fido
Config: $FIDO_HOME/.env
State: $FIDO_HOME/state/<workspace>/ (undo.json + suspends/)
Activate in this shell: source "$BASHRC"
(or just open a new terminal.)
Then run, from any project directory:
fido # work on the current directory
fido /path/to/project # work on a specific directory
Remember to set OPENROUTER_API_KEY in $FIDO_HOME/.env.
EOF
}
do_uninstall() {
remove_from_path
if [ -d "$FIDO_HOME" ]; then
info "Removing $FIDO_HOME"
rm -rf "$FIDO_HOME"
else
warn "$FIDO_HOME does not exist — nothing to remove."
fi
info "Fido uninstalled. Open a new shell (or re-source $BASHRC) to drop the PATH entry."
}
case "${1:-}" in
""|--install|-i) do_install ;;
--uninstall|-u) do_uninstall ;;
--help|-h) usage ;;
*) die "Unknown argument: $1 (try --help)" ;;
esac