lardon3d/.opencode/bin/opencode-away
2026-08-09 00:34:51 +02:00

124 lines
2.8 KiB
Bash
Executable file

#!/usr/bin/env bash
set -u
usage() {
printf '%s\n' 'usage: opencode-away [--check] [opencode arguments...]'
}
require_command() {
command -v "$1" >/dev/null 2>&1 || {
printf 'opencode-away: required command not found: %s\n' "$1" >&2
return 1
}
}
if [[ ${1-} == --help ]]; then
usage
exit 0
fi
check_only=0
if [[ ${1-} == --check ]]; then
check_only=1
shift
fi
require_command opencode || exit 127
require_command systemd-inhibit || exit 127
require_command git || exit 127
require_command ps || exit 127
require_command kill || exit 127
if [[ $(systemd-inhibit --help 2>&1) != *handle-lid-switch* ]]; then
printf '%s\n' 'opencode-away: systemd-inhibit lacks handle-lid-switch' >&2
exit 3
fi
if ! git rev-parse --show-toplevel >/dev/null 2>&1; then
printf '%s\n' 'opencode-away: run this command inside a Git worktree' >&2
exit 2
fi
if ((check_only)); then
printf '%s\n' 'OpenCode away mode check: OK'
printf 'repository: %s\n' "$(git rev-parse --show-toplevel)"
printf 'opencode: %s\n' "$(command -v opencode)"
printf 'systemd-inhibit: %s\n' "$(command -v systemd-inhibit)"
exit 0
fi
declare -a suspended_pids=()
cleanup_done=0
child_pid=0
restore_swayidle() {
local pid
((cleanup_done)) && return 0
cleanup_done=1
for pid in "${suspended_pids[@]}"; do
if kill -0 "$pid" 2>/dev/null &&
[[ $(ps -o comm= -p "$pid" 2>/dev/null) == swayidle ]]; then
kill -CONT "$pid" 2>/dev/null || true
fi
done
if ((${#suspended_pids[@]})); then
printf '%s\n' 'swayidle restored'
fi
}
on_signal() {
local signal=$1
if ((child_pid > 0)) && kill -0 "$child_pid" 2>/dev/null; then
kill -s "$signal" "$child_pid" 2>/dev/null || true
wait "$child_pid" 2>/dev/null || true
fi
restore_swayidle
trap - "$signal"
kill -s "$signal" "$$"
}
trap restore_swayidle EXIT
trap 'on_signal HUP' HUP
trap 'on_signal INT' INT
trap 'on_signal TERM' TERM
while read -r pid state; do
[[ $pid =~ ^[0-9]+$ ]] || continue
[[ $state == T* ]] && continue
if kill -STOP "$pid" 2>/dev/null; then
suspended_pids+=("$pid")
fi
done < <(ps -C swayidle -o pid=,stat= 2>/dev/null)
printf '%s\n' 'OpenCode away mode'
printf '%s\n' 'sleep inhibited'
printf '%s\n' 'lid switch inhibited'
if ((${#suspended_pids[@]})); then
printf 'swayidle suspended:'
printf ' %s' "${suspended_pids[@]}"
printf '\n'
else
printf '%s\n' 'swayidle suspended: none active'
fi
export LARDON_OPENCODE_LONG_RUN=1
if [[ -n ${OPENCODE_AWAY_COMMAND-} ]]; then
child_command=(bash -c "$OPENCODE_AWAY_COMMAND")
else
child_command=(opencode --auto "$@")
fi
systemd-inhibit \
--what=sleep:idle:handle-lid-switch \
--who='OpenCode Long Run' \
--why='Autonomous Lardon3D development ticket' \
--mode=block \
"${child_command[@]}" &
child_pid=$!
wait "$child_pid"
child_status=$?
child_pid=0
restore_swayidle
exit "$child_status"