app
hook
Public Made by Adomby adom
Registry-native cross-agent auto-update hook, plus claude-rc, the keeper for Claude Remote Control. Keeps adom/core apps and skills current from wiki.adom.inc on every Claude Code and Codex prompt, and keeps `claude rc` alive so users can open AI threads on their container from the Claude mobile app or claude.ai/code.
← Commit history
Hook: HOME-safe cron registration + loud missing-CLI (adom/hook#3), refresh the install-lock note (#2)
2 files changed
+39−6
check-updates.sh+17−4@@ -43,7 +43,9 @@ now=$(date +%s 2>/dev/null || echo 0) # the last update succeeded or none has run. if [ -f "$STATUS" ]; then st="$(cat "$STATUS" 2>/dev/null)"- if [ "$st" != "running" ] && [ -n "$st" ] && [ "$st" != "0" ]; then+ # 'cli-missing' is reported by its own check below, with its own remedy, so it+ # is not re-reported here as a failed update.+ if [ "$st" != "running" ] && [ "$st" != "cli-missing" ] && [ -n "$st" ] && [ "$st" != "0" ]; then reason="$(tail -n 3 "$LOG" 2>/dev/null | tr '\n' ' ' | cut -c1-300)" echo "adom: the last background auto-update FAILED (exit $st) -- the fleet may be behind wiki.adom.inc. See why with 'adom-wiki pkg install adom/core'. Recent output: ${reason:-<none>}" # Fall through and retry below; a transient failure self-heals, a real one@@ -59,7 +61,16 @@ if [ -z "${ADOM_HOOK_FORCE:-}" ] && [ "$last" -gt 0 ] && [ $(( now - last )) -lt fi touch "$STAMP" 2>/dev/null -command -v adom-wiki >/dev/null 2>&1 || exit 0+# The CLI is the whole update mechanism, so its absence means this container has+# STOPPED updating. Exiting 0 made that indistinguishable from "nothing to do"+# (adom/hook#3), the same silence this hook exists to break. Say it, and leave a+# status other surfaces can read, while staying non-fatal: a prompt hook must+# never block the user's session.+if ! command -v adom-wiki >/dev/null 2>&1; then+ echo "adom: auto-update is NOT running: the adom-wiki CLI is not on PATH (checked \$HOME/.local/bin and \$PATH). This container will drift behind wiki.adom.inc until the CLI is reinstalled."+ echo "cli-missing" > "$STATUS" 2>/dev/null+ exit 0+fi # --- 3. Don't stack a second updater on top of one still running. ------------- # But treat a 'running' marker older than RUN_STALE_AFTER as crashed (container@@ -90,8 +101,10 @@ fi # `cp: cannot stat 'skills/.../SKILL.md'`. The flock below serializes the hook's # own updaters: the second to arrive skips instead of stacking. It is held for the # WHOLE background update (inside the subshell), not just the parent launch.-# (It does NOT cover a MANUAL `adom-wiki pkg install` racing the hook -- that needs-# a CLI-level install lock. See adom/hook #1 follow-up.)+# A MANUAL `adom-wiki pkg install` racing the hook is covered too, since+# adom-wiki-cli 1.0.39: every mutating pkg verb takes an exclusive lock on+# PREFIX/.install.lock and extracts atomically (stage into a sibling dir, then+# rename), so no caller can observe a half-written module dir. (adom/hook#2) echo running > "$STATUS" 2>/dev/null ( if command -v flock >/dev/null 2>&1; then
install.sh+22−2@@ -95,10 +95,30 @@ wire "${HOME}/.codex/hooks.json" 0 CRON_LINE_INTERVAL="*/30 * * * * $HOOK_CMD >/dev/null 2>&1" CRON_LINE_REBOOT="@reboot $HOOK_CMD >/dev/null 2>&1" if command -v crontab >/dev/null 2>&1; then- # Idempotent: strip any prior adom-core-update entries, then re-add both.- if { crontab -l 2>/dev/null | grep -v "adom-core-update.sh" || true; \+ # Idempotent, and HOME-SAFE (adom/hook#3): crontab is a per-USER resource, not+ # per-HOME. Stripping every line matching "adom-core-update.sh" meant an+ # install run with a non-default HOME (an isolated test, a service account+ # sharing the user) deleted the REAL entries and repointed this user's cron at+ # the foreign HOME -- the container then stopped updating and said nothing,+ # which is the exact failure class this hook exists to prevent. Only ever+ # remove lines that invoke THIS hook path.+ cron_filter() {+ # Fixed-string match on the full hook path, so /home/a/... never matches+ # /home/b/..., and a regex metacharacter in HOME cannot widen the match.+ grep -vF "$HOOK" 2>/dev/null || true+ }+ if { crontab -l 2>/dev/null | cron_filter; \ echo "$CRON_LINE_INTERVAL"; echo "$CRON_LINE_REBOOT"; } | crontab - 2>/dev/null; then echo " registered cron for headless updates (*/30 + @reboot)"+ # Another HOME's hook in the same user crontab is legal but almost always a+ # mistake (a stray isolated-test install). Name it instead of leaving two+ # updaters racing invisibly.+ others="$(crontab -l 2>/dev/null | grep -F "adom-core-update.sh" | grep -vF "$HOOK" || true)"+ if [ -n "$others" ]; then+ echo " note: this user's crontab also runs the hook from ANOTHER home:" >&2+ echo "$others" | sed 's/^/ /' >&2+ echo " that is usually a leftover from an isolated-HOME install; remove it with 'crontab -e' if so." >&2+ fi if ! pgrep -x crond >/dev/null 2>&1 && ! pgrep -x cron >/dev/null 2>&1; then echo " warning: crond is NOT running, so the schedule will not fire. Start cron in this image," >&2 echo " or have the app call '$HOOK' on its own loop." >&2