175 lines
5.9 KiB
Bash
Executable File
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
|