initial commit

This commit is contained in:
2026-03-22 02:25:16 +01:00
commit eb72820ce9
42 changed files with 2506 additions and 0 deletions
Executable
+211
View File
@@ -0,0 +1,211 @@
#!/bin/bash
set -e
CLI_BIN="Hush.Cli/bin/Release/net10.0/linux-x64/publish/Hush.Cli"
INSTALL_PREFIX="${INSTALL_PREFIX:-/usr}"
BIN_DIR="$INSTALL_PREFIX/bin"
COMPLETION_DIR="$INSTALL_PREFIX/share/zsh/site-functions"
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
info() { echo "[install] $*"; }
success() { echo "[install] $*"; }
warn() { echo "[install] WARNING: $*" >&2; }
die() { echo "[install] ERROR: $*" >&2; exit 1; }
require_root() {
if [[ $EUID -ne 0 ]]; then
die "This script must be run as root (use sudo)."
fi
}
detect_init() {
if command -v systemctl &>/dev/null && systemctl --version &>/dev/null 2>&1; then
echo "systemd"
elif [[ -f /sbin/openrc-run ]] || [[ -f /usr/sbin/openrc-run ]] || command -v rc-service &>/dev/null; then
echo "openrc"
else
echo "none"
fi
}
# ---------------------------------------------------------------------------
# Build
# ---------------------------------------------------------------------------
build() {
info "Building Hush with AOT compilation..."
# If running as root (via sudo), build as the real user so that the
# output artifacts are not owned by root.
if [[ $EUID -eq 0 && -n "$SUDO_USER" ]]; then
sudo -u "$SUDO_USER" bash build.sh
else
bash build.sh
fi
}
# ---------------------------------------------------------------------------
# Install binary
# ---------------------------------------------------------------------------
install_binary() {
[[ -f "$CLI_BIN" ]] || die "Binary not found: $CLI_BIN — run build.sh first or let install.sh build it."
info "Installing binary to $BIN_DIR/hush..."
install -Dm755 "$CLI_BIN" "$BIN_DIR/hush"
success "Installed: $BIN_DIR/hush"
}
# ---------------------------------------------------------------------------
# Zsh completion
# ---------------------------------------------------------------------------
install_completion() {
info "Installing zsh completion to $COMPLETION_DIR/_hush..."
install -Dm644 completions/_hush "$COMPLETION_DIR/_hush"
success "Zsh completion installed."
info " Add the following to your .zshrc if not already present:"
info " fpath=($COMPLETION_DIR \$fpath)"
info " autoload -Uz compinit && compinit"
}
# ---------------------------------------------------------------------------
# systemd user service
# ---------------------------------------------------------------------------
install_systemd() {
info "Installing systemd user service..."
local run_user="${SUDO_USER:-$USER}"
local user_home uid service_dir service_file
user_home=$(getent passwd "$run_user" | cut -d: -f6)
uid=$(id -u "$run_user")
service_dir="$user_home/.config/systemd/user"
service_file="$service_dir/hush.service"
mkdir -p "$service_dir"
chown "$run_user:" "$service_dir"
cat > "$service_file" <<EOF
[Unit]
Description=Hush speech-to-text daemon
After=graphical-session.target pipewire.service
[Service]
ExecStart=$BIN_DIR/hush daemon
Restart=on-failure
RestartSec=3
[Install]
WantedBy=default.target
EOF
chown "$run_user:" "$service_file"
sudo -u "$run_user" \
XDG_RUNTIME_DIR="/run/user/$uid" \
HOME="$user_home" \
systemctl --user daemon-reload
sudo -u "$run_user" \
XDG_RUNTIME_DIR="/run/user/$uid" \
HOME="$user_home" \
systemctl --user enable --now hush.service
success "systemd user service enabled and started."
}
# ---------------------------------------------------------------------------
# OpenRC service
# ---------------------------------------------------------------------------
install_openrc() {
local rc_file="/etc/init.d/hush"
local rc_conf="/etc/conf.d/hush"
info "Installing OpenRC service..."
# Determine the user to run the daemon as
local run_user="${SUDO_USER:-$(logname 2>/dev/null || echo "$USER")}"
cat > "$rc_file" <<EOF
#!/sbin/openrc-run
name="hush"
description="Hush speech-to-text daemon"
command="$BIN_DIR/hush"
command_args="daemon"
command_user="${run_user}"
# XDG_RUNTIME_DIR is required by the daemon for the Unix socket
export XDG_RUNTIME_DIR="/run/user/\$(id -u $run_user)"
pidfile="/run/\${RC_SVCNAME}.pid"
command_background=true
depend() {
after graphical
use logger
}
EOF
chmod 755 "$rc_file"
cat > "$rc_conf" <<EOF
# Configuration file for the hush OpenRC service.
# Run 'hush setup' to configure Hush itself.
EOF
rc-update add hush default
rc-service hush start
success "OpenRC service installed, added to default runlevel, and started."
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
main() {
local init_system
init_system=$(detect_init)
# Build if binary is missing
if [[ ! -f "$CLI_BIN" ]]; then
build
else
info "Binary already built, skipping build step."
info " (Delete the publish directory and re-run to force a rebuild.)"
fi
require_root
install_binary
install_completion
case "$init_system" in
systemd)
info "Detected init system: systemd"
install_systemd
;;
openrc)
info "Detected init system: OpenRC"
install_openrc
;;
none)
warn "Could not detect a supported init system (systemd or OpenRC)."
warn "Start the daemon manually with: hush daemon"
;;
esac
echo ""
success "Installation complete!"
echo ""
echo " Run 'hush setup' to configure your API keys and preferences."
echo " Run 'hush status' to check daemon status."
echo ""
}
main "$@"