diff --git a/services/inbox-notify-runit/README.md b/services/inbox-notify-runit/README.md deleted file mode 100644 index c1fd983..0000000 --- a/services/inbox-notify-runit/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# anvillm-inbox-notify runit service - -Runit service for the [`anvillm-inbox-notify`](../../scripts/anvillm-inbox-notify) daemon. - -## What it does - -Streams the AnviLLM event bus (`9p read anvillm/events`) and fires desktop -notifications via `notify-send` when messages of configured types arrive in -the user's inbox. - -Default notification types: `APPROVAL_REQUEST`, `REVIEW_REQUEST`. - -Configurable via `~/.config/anvillm/notifications.yaml`: - -```yaml -notify_on: - - APPROVAL_REQUEST - - REVIEW_REQUEST - # - QUERY_REQUEST # uncomment to also notify on queries -``` - -## Installation - -### System-wide (runit) - -```sh -sudo cp -r services/inbox-notify-runit /etc/sv/anvillm-inbox-notify -sudo ln -s /etc/sv/anvillm-inbox-notify /var/service/anvillm-inbox-notify -``` - -### Per-user (runit with ~/.config/service) - -```sh -mkdir -p ~/.config/service -cp -r services/inbox-notify-runit ~/.config/service/anvillm-inbox-notify -sv up anvillm-inbox-notify -``` - -### Manual (foreground) - -```sh -./scripts/anvillm-inbox-notify -``` - -## Prerequisites - -- `anvillm-inbox-notify` script installed in `PATH` -- `notify-send` (from `libnotify` or `dunst`) -- `jq` ≥ 1.6 -- `9p` command connected to a running `anvillm` diff --git a/services/inbox-notify-runit/finish b/services/inbox-notify-runit/finish deleted file mode 100755 index be8b51b..0000000 --- a/services/inbox-notify-runit/finish +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# runit finish script for anvillm-inbox-notify -# Called when the service stops (daemon exited or was killed). - -echo "anvillm-inbox-notify stopped" diff --git a/services/inbox-notify-runit/run b/services/inbox-notify-runit/run deleted file mode 100755 index 7061e33..0000000 --- a/services/inbox-notify-runit/run +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# runit service script for anvillm-inbox-notify -# -# Monitors the AnviLLM event stream and fires desktop notifications when -# messages of configured types (default: APPROVAL_REQUEST, REVIEW_REQUEST) -# arrive in the user's inbox. -# -# To install this service: -# 1. Copy this directory to /etc/sv/anvillm-inbox-notify -# 2. Create symlink: ln -s /etc/sv/anvillm-inbox-notify /var/service/anvillm-inbox-notify -# -# Or for per-user service management with runit: -# mkdir -p ~/.config/service -# cp -r services/inbox-notify-runit ~/.config/service/anvillm-inbox-notify -# sv up anvillm-inbox-notify - -exec 2>&1 - -export HOME="${HOME:-/home/$(whoami)}" -export PATH="${HOME}/bin:/usr/local/bin:/usr/bin:/bin" -export NAMESPACE="${NAMESPACE:-/tmp/ns.$(whoami).:0}" -export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" -export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" - -# Make DISPLAY available for desktop notifications. -# Adjust if your display is different (e.g., :1, wayland, etc.) -export DISPLAY="${DISPLAY:-:0}" -export DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-unix:path=/run/user/$(id -u)/bus}" - -echo "Starting anvillm-inbox-notify..." - -exec chpst -u "$(whoami)" anvillm-inbox-notify diff --git a/services/systemd/anvillm-inbox-notify.service b/services/systemd/anvillm-inbox-notify.service deleted file mode 100644 index 47a7499..0000000 --- a/services/systemd/anvillm-inbox-notify.service +++ /dev/null @@ -1,25 +0,0 @@ -[Unit] -Description=AnviLLM Inbox Notification Daemon -Documentation=https://github.com/lkn/anvillm -After=default.target - -[Service] -Type=simple - -# Inherit DISPLAY and DBUS from user session for desktop notifications. -# Uncomment and set if your session differs from :0. -# Environment="DISPLAY=:0" -# Environment="DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/bus" - -# Namespace for 9P mount (default matches anvillm default). -# Override if you use a non-default namespace. -# Environment="NAMESPACE=/tmp/ns.%u.:0" - -ExecStart=%h/bin/anvillm-inbox-notify - -# Restart if the daemon exits (e.g. anvillm restarted and the 9p read broke). -Restart=on-failure -RestartSec=5s - -[Install] -WantedBy=default.target diff --git a/services/sysvinit/anvillm-inbox-notify b/services/sysvinit/anvillm-inbox-notify deleted file mode 100755 index 36de22a..0000000 --- a/services/sysvinit/anvillm-inbox-notify +++ /dev/null @@ -1,185 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: anvillm-inbox-notify -# Required-Start: $local_fs $syslog -# Required-Stop: $local_fs $syslog -# Should-Start: $network dbus -# Should-Stop: $network dbus -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: AnviLLM inbox notification daemon -# Description: Monitors the AnviLLM event stream and delivers desktop -# notifications (via notify-send) when messages of configured -# types (default: APPROVAL_REQUEST, REVIEW_REQUEST) arrive in -# the human user's inbox. -### END INIT INFO - -# ── configuration ───────────────────────────────────────────────────────────── -# -# Set ANVILLM_USER to the login name of the desktop user who should receive -# notifications. The daemon needs that user's X11 DISPLAY and D-Bus session -# bus address; this script discovers them automatically from /proc. -# -# Override in /etc/default/anvillm-inbox-notify (sourced below if it exists). -# -ANVILLM_USER="${ANVILLM_USER:-}" - -NAME="anvillm-inbox-notify" -DAEMON="/usr/local/bin/anvillm-inbox-notify" -PIDFILE="/var/run/${NAME}.pid" -LOGFILE="/var/log/${NAME}.log" - -# Source distro defaults (if any). -[ -r /etc/default/anvillm-inbox-notify ] && . /etc/default/anvillm-inbox-notify - -# ── sanity checks ───────────────────────────────────────────────────────────── - -if [ -z "$ANVILLM_USER" ]; then - echo "${NAME}: ANVILLM_USER is not set." >&2 - echo " Set it in /etc/default/anvillm-inbox-notify:" >&2 - echo " ANVILLM_USER=yourlogin" >&2 - exit 6 # LSB: program not configured -fi - -if [ ! -x "$DAEMON" ]; then - echo "${NAME}: daemon not found at ${DAEMON}" >&2 - exit 5 # LSB: program not installed -fi - -# ── helpers ─────────────────────────────────────────────────────────────────── - -# get_env_var VAR USER -# Read an environment variable from any running process owned by USER. -get_env_var() { - local var="$1" user="$2" - local pid - pid=$(pgrep -u "$user" -x Xorg 2>/dev/null || pgrep -u "$user" -x X 2>/dev/null || pgrep -u "$user" 2>/dev/null | head -1) - [ -z "$pid" ] && return 1 - # /proc//environ is null-separated; grep for the variable and extract value - tr '\0' '\n' < "/proc/${pid}/environ" 2>/dev/null | grep "^${var}=" | head -1 | cut -d= -f2- -} - -# discover_session_env -# Populates DISPLAY_ENV and DBUS_ENV for ANVILLM_USER. -discover_session_env() { - DISPLAY_ENV=$(get_env_var DISPLAY "$ANVILLM_USER") - DBUS_ENV=$(get_env_var DBUS_SESSION_BUS_ADDRESS "$ANVILLM_USER") - - if [ -z "$DISPLAY_ENV" ]; then - # Fall back to :0 — correct for a single local X session - DISPLAY_ENV=":0" - fi - - if [ -z "$DBUS_ENV" ]; then - # Try the well-known systemd path for the user's UID - local uid - uid=$(id -u "$ANVILLM_USER" 2>/dev/null) - if [ -n "$uid" ]; then - DBUS_ENV="unix:path=/run/user/${uid}/bus" - fi - fi -} - -daemon_running() { - [ -s "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null -} - -# ── actions ─────────────────────────────────────────────────────────────────── - -do_start() { - if daemon_running; then - echo "${NAME} is already running (PID $(cat "$PIDFILE"))." - return 0 # LSB: 0 = already running is not an error - fi - - discover_session_env - - echo "Starting ${NAME} as ${ANVILLM_USER} (DISPLAY=${DISPLAY_ENV})..." - - su -s /bin/sh -l "$ANVILLM_USER" -c " - export DISPLAY='${DISPLAY_ENV}' - export DBUS_SESSION_BUS_ADDRESS='${DBUS_ENV}' - nohup '${DAEMON}' >> '${LOGFILE}' 2>&1 & - echo \$! > '${PIDFILE}' - " - - # Brief wait and confirm. - sleep 1 - if daemon_running; then - echo "${NAME} started (PID $(cat "$PIDFILE"))." - return 0 - else - echo "${NAME}: failed to start — check ${LOGFILE}" >&2 - rm -f "$PIDFILE" - return 1 - fi -} - -do_stop() { - if ! daemon_running; then - echo "${NAME} is not running." - rm -f "$PIDFILE" - return 0 # LSB: 0 = already stopped is not an error - fi - - local pid - pid=$(cat "$PIDFILE") - echo "Stopping ${NAME} (PID ${pid})..." - kill "$pid" 2>/dev/null - # Wait up to 5 s for the process to exit. - local i=0 - while kill -0 "$pid" 2>/dev/null && [ "$i" -lt 5 ]; do - sleep 1 - i=$((i + 1)) - done - if kill -0 "$pid" 2>/dev/null; then - echo "${NAME}: still running after 5 s, sending SIGKILL..." - kill -9 "$pid" 2>/dev/null - fi - rm -f "$PIDFILE" - echo "${NAME} stopped." - return 0 -} - -do_status() { - if daemon_running; then - echo "${NAME} is running (PID $(cat "$PIDFILE"))." - return 0 # LSB status: 0 = running - elif [ -s "$PIDFILE" ]; then - echo "${NAME} is dead but PID file ${PIDFILE} exists." - return 1 # LSB status: 1 = dead, pidfile exists - else - echo "${NAME} is not running." - return 3 # LSB status: 3 = not running - fi -} - -# ── dispatch ────────────────────────────────────────────────────────────────── - -case "$1" in - start) - do_start - ;; - stop) - do_stop - ;; - restart|force-reload) - do_stop - sleep 1 - do_start - ;; - reload) - # The daemon re-reads its config on next startup; no live reload needed. - echo "${NAME}: reload not supported — use restart instead." - exit 3 # LSB: unimplemented feature - ;; - status) - do_status - ;; - *) - echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2 - exit 2 # LSB: invalid argument - ;; -esac - -exit $? diff --git a/services/sysvinit/rc.anvillm-inbox-notify b/services/sysvinit/rc.anvillm-inbox-notify deleted file mode 100755 index c13ead9..0000000 --- a/services/sysvinit/rc.anvillm-inbox-notify +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/sh -# /etc/rc.d/rc.anvillm-inbox-notify -# -# Start/stop/restart the AnviLLM inbox notification daemon. -# -# This script follows Slackware rc conventions: -# - Enable service: chmod 755 /etc/rc.d/rc.anvillm-inbox-notify -# - Disable service: chmod 644 /etc/rc.d/rc.anvillm-inbox-notify -# -# To start automatically at boot, add to /etc/rc.d/rc.local: -# if [ -x /etc/rc.d/rc.anvillm-inbox-notify ]; then -# /etc/rc.d/rc.anvillm-inbox-notify start -# fi -# -# To stop cleanly at shutdown, add to /etc/rc.d/rc.local_shutdown: -# if [ -x /etc/rc.d/rc.anvillm-inbox-notify ]; then -# /etc/rc.d/rc.anvillm-inbox-notify stop -# fi -# -# ── configuration ───────────────────────────────────────────────────────────── -# -# ANVILLM_USER Login name of the desktop user who receives notifications. -# The daemon monitors that user's AnviLLM event stream and fires -# notify-send desktop notifications for APPROVAL_REQUEST and -# REVIEW_REQUEST messages (configurable in -# ~/.config/anvillm/notifications.yaml). -# -ANVILLM_USER="${ANVILLM_USER:-}" - -DAEMON="/usr/local/bin/anvillm-inbox-notify" -PIDFILE="/var/run/anvillm-inbox-notify.pid" -LOGFILE="/var/log/anvillm-inbox-notify.log" - -# ── helpers ─────────────────────────────────────────────────────────────────── - -# get_user_env VAR -# Reads an environment variable from a running process owned by $ANVILLM_USER. -# Tries the Xorg/X process first (most likely to have DISPLAY set), then any -# process owned by that user. -get_user_env() { - local var="$1" - local pid - - pid=$(pgrep -u "$ANVILLM_USER" -x Xorg 2>/dev/null | head -1) - [ -z "$pid" ] && pid=$(pgrep -u "$ANVILLM_USER" -x X 2>/dev/null | head -1) - [ -z "$pid" ] && pid=$(pgrep -u "$ANVILLM_USER" 2>/dev/null | head -1) - [ -z "$pid" ] && return 1 - - tr '\0' '\n' < "/proc/${pid}/environ" 2>/dev/null | \ - grep "^${var}=" | head -1 | cut -d= -f2- -} - -anvillm_start() { - # Guard: already running? - if [ -s "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then - echo "anvillm-inbox-notify is already running." - return - fi - - if [ -z "$ANVILLM_USER" ]; then - echo "anvillm-inbox-notify: ANVILLM_USER is not set — edit this script or set the variable." >&2 - return - fi - - if [ ! -x "$DAEMON" ]; then - echo "anvillm-inbox-notify: ${DAEMON} not found or not executable." >&2 - return - fi - - # Discover the user's X11 display and D-Bus session bus address. - DISPLAY_VAL=$(get_user_env DISPLAY) - [ -z "$DISPLAY_VAL" ] && DISPLAY_VAL=":0" - - DBUS_VAL=$(get_user_env DBUS_SESSION_BUS_ADDRESS) - if [ -z "$DBUS_VAL" ]; then - local uid - uid=$(id -u "$ANVILLM_USER" 2>/dev/null) - [ -n "$uid" ] && DBUS_VAL="unix:path=/run/user/${uid}/bus" - fi - - echo "Starting anvillm-inbox-notify (user=${ANVILLM_USER}, DISPLAY=${DISPLAY_VAL})..." - - su -s /bin/sh -l "$ANVILLM_USER" -c " - export DISPLAY='${DISPLAY_VAL}' - export DBUS_SESSION_BUS_ADDRESS='${DBUS_VAL}' - nohup '${DAEMON}' >> '${LOGFILE}' 2>&1 & - echo \$! > '${PIDFILE}' - " -} - -anvillm_stop() { - if [ ! -s "$PIDFILE" ]; then - echo "anvillm-inbox-notify is not running (no PID file)." - return - fi - - local pid - pid=$(cat "$PIDFILE") - - if ! kill -0 "$pid" 2>/dev/null; then - echo "anvillm-inbox-notify: stale PID file — removing." - rm -f "$PIDFILE" - return - fi - - echo "Stopping anvillm-inbox-notify (PID ${pid})..." - kill "$pid" 2>/dev/null - rm -f "$PIDFILE" -} - -anvillm_restart() { - anvillm_stop - sleep 1 - anvillm_start -} - -anvillm_status() { - if [ -s "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then - echo "anvillm-inbox-notify is running (PID $(cat "$PIDFILE"))." - else - echo "anvillm-inbox-notify is not running." - fi -} - -# ── dispatch ────────────────────────────────────────────────────────────────── - -case "$1" in - start) - anvillm_start - ;; - stop) - anvillm_stop - ;; - restart) - anvillm_restart - ;; - status) - anvillm_status - ;; - *) - echo "Usage: $0 {start|stop|restart|status}" - ;; -esac