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
install.sh+62−35@@ -1,5 +1,8 @@ #!/usr/bin/env bash-# Wire the adom auto-update hook into Claude Code and Codex, idempotently.+# Wire the adom auto-update hook into Claude Code and Codex, idempotently, and+# retire any legacy update hook (gallia's, or the pre-rename check-updates.sh) so+# an existing workspace MIGRATES to the registry-native hook instead of stacking+# both. The current hook is adom-core-update.sh, which is preserved. set -euo pipefail PKG_DIR="$(cd "$(dirname "$0")" && pwd)" @@ -9,61 +12,85 @@ mkdir -p "$HOOK_DIR" install -m 0755 "$PKG_DIR/check-updates.sh" "$HOOK" HOOK_CMD="bash $HOOK" +# Drop the stale launcher file from older adom/hook installs (now adom-core-update.sh).+rm -f "${HOOK_DIR}/check-updates.sh" 2>/dev/null || true+ if ! command -v python3 >/dev/null 2>&1; then echo " warning: python3 not found; cannot wire agent configs. Hook script staged at $HOOK." >&2 exit 0 fi -# --- Claude Code: ~/.claude/settings.json -> hooks.UserPromptSubmit ----CLAUDE="${HOME}/.claude/settings.json"-mkdir -p "$(dirname "$CLAUDE")"-python3 - "$CLAUDE" "$HOOK_CMD" <<'PY'-import json, os, sys-path, cmd = sys.argv[1], sys.argv[2]+# Wire HOOK_CMD into one agent config's hooks.UserPromptSubmit, removing any legacy+# auto-update hook first. $1 = config path, $2 = "1" to include a timeout field.+wire() {+ local path="$1" with_timeout="$2"+ mkdir -p "$(dirname "$path")"+ python3 - "$path" "$HOOK_CMD" "$with_timeout" <<'PY'+import json, sys+path, cmd, with_timeout = sys.argv[1], sys.argv[2], sys.argv[3] == "1" try: with open(path) as f: d = json.load(f) if not isinstance(d, dict): d = {} except Exception: d = {} ups = d.setdefault("hooks", {}).setdefault("UserPromptSubmit", [])+# A legacy update hook is any command pointing at a check-updates.sh (gallia's+# hooks/check-updates.sh, or this package's own pre-rename name). adom-core-update.sh+# does not match, so the current hook is never removed.+def is_legacy(h):+ return isinstance(h, dict) and "check-updates.sh" in str(h.get("command", ""))+removed = 0+kept_groups = []+for g in ups:+ if not isinstance(g, dict):+ kept_groups.append(g); continue+ hooks = g.get("hooks", [])+ keep = [h for h in hooks if not is_legacy(h)]+ removed += len(hooks) - len(keep)+ if keep:+ g["hooks"] = keep+ kept_groups.append(g)+ups[:] = kept_groups present = any(- h.get("command") == cmd+ isinstance(h, dict) and h.get("command") == cmd for g in ups if isinstance(g, dict)- for h in g.get("hooks", []) if isinstance(h, dict)+ for h in g.get("hooks", []) )-if present:- print(" adom-core-update already wired in ~/.claude/settings.json")+changed = removed > 0+if not present:+ entry = {"type": "command", "command": cmd}+ if with_timeout:+ entry["timeout"] = 15+ ups.append({"hooks": [entry]})+ changed = True+if changed:+ with open(path, "w") as f:+ json.dump(d, f, indent=2)+ note = " (retired %d legacy hook(s))" % removed if removed else ""+ print(" wired adom-core-update into %s%s" % (path, note)) else:- ups.append({"hooks": [{"type": "command", "command": cmd, "timeout": 15}]})- with open(path, "w") as f: json.dump(d, f, indent=2)- print(" wired adom-core-update into ~/.claude/settings.json")+ print(" adom-core-update already wired in %s" % path) PY+}++wire "${HOME}/.claude/settings.json" 1+wire "${HOME}/.codex/hooks.json" 0 -# --- Codex: ~/.codex/hooks.json -> hooks.UserPromptSubmit ----# Codex mirrors Claude's hook events and additionalContext channel. This shape is-# best-effort; verify against a live Codex install before relying on it there.-CODEX="${HOME}/.codex/hooks.json"-mkdir -p "$(dirname "$CODEX")"-python3 - "$CODEX" "$HOOK_CMD" <<'PY'-import json, os, sys-path, cmd = sys.argv[1], sys.argv[2]+# Retire a gallia statusline if one is wired (gallia is gone; revert to default).+# Targeted: only removed when the statusline command points at gallia.+python3 - "${HOME}/.claude/settings.json" <<'PY'+import json, sys+path = sys.argv[1] try: with open(path) as f: d = json.load(f)- if not isinstance(d, dict): d = {}+ if not isinstance(d, dict): raise ValueError except Exception:- d = {}-ups = d.setdefault("hooks", {}).setdefault("UserPromptSubmit", [])-present = any(- h.get("command") == cmd- for g in ups if isinstance(g, dict)- for h in g.get("hooks", []) if isinstance(h, dict)-)-if present:- print(" adom-core-update already wired in ~/.codex/hooks.json")-else:- ups.append({"hooks": [{"type": "command", "command": cmd}]})+ sys.exit(0)+sl = d.get("statusLine")+if isinstance(sl, dict) and "gallia" in str(sl.get("command", "")):+ d.pop("statusLine", None) with open(path, "w") as f: json.dump(d, f, indent=2)- print(" wired adom-core-update into ~/.codex/hooks.json")+ print(" retired the gallia statusline (reverted to default)") PY # Stage the skill doc for discovery.
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "hook",- "version": "1.1.5",+ "version": "1.1.6", "type": "app", "org": "adom", "bundled": true,
page.json+1−1@@ -1,6 +1,6 @@ { "slug": "hook",- "version": "1.1.5",+ "version": "1.1.6", "type": "app", "org": "adom", "bundled": true,