← Commit history

Publish 1.3.1

John Lauer ·d3a0b8041b ·1mo ago ·parent cde759e
4 files changed +35−9
SKILL.md+5−2
@@ -151,8 +151,11 @@ used. Detection is `ADOM_DESKTOP_MODE=local` plus a live crond.  ## Facts worth knowing before you debug it -- `claude rc` skips its "Enable Remote Control? (y/n)" prompt when stdin is not a TTY, so-  the watchdog launches it headless with `setsid nohup ... </dev/null`.+- `claude rc` skips its "Enable Remote Control? (y/n)" prompt when stdin is not a TTY, but+  it still READS stdin (it waits for a keypress to show the QR code) and exits on EOF. So the+  keeper launches it with a stdin that never closes (`sleep infinity | exec claude rc ...`),+  never with `</dev/null`: that variant connects and dies within a second, five times, and+  ends in `state=failed` (adom/hook 1.3.1 fix, found on an Adom cloud container). - Prereqs: `claude` on PATH, a logged-in subscription account, and workspace trust   accepted for `~/project` (`hasTrustDialogAccepted` in `~/.claude.json`). The hook only   offers when these hold, which inside a running session they already do.
claude-rc+13−2
@@ -32,7 +32,11 @@ SELF="$HOME/.local/bin/claude-rc" PROJECT_DIR="${CLAUDE_RC_PROJECT_DIR:-$HOME/project}" # Anchored to the START of the cmdline so a shell whose command text merely # mentions "claude rc" (this script's own callers, a chat transcript) never matches.-PAT='^\S*/claude (rc|remote-control)( |$)'+# The path prefix is OPTIONAL: launched from PATH the cmdline is a bare `claude rc ...`,+# and the old mandatory `\S*/` never matched it, so the watchdog relaunched a server that+# was already up (five times an hour -> state=failed) and `status` said "not running"+# next to a live pid. Verified on an Adom cloud container 2026-08-30.+PAT='^(\S*/)?claude (rc|remote-control)( |$)' mkdir -p "$STATE_DIR"  # ---- state file: KEY=VALUE lines -------------------------------------------@@ -60,6 +64,7 @@ running_pid() { pgrep -f "$PAT" | head -1; } # tear down its relay connection, so a bare pkill + immediate pgrep still sees it. stop_server() {   pkill -f "$PAT" 2>/dev/null || return 0+  pkill -f '^bash -c sleep infinity \| exec claude rc' 2>/dev/null || true   local i; for i in 1 2 3 4 5 6 7 8; do [ -z "$(running_pid)" ] && return 0; sleep 1; done   pkill -9 -f "$PAT" 2>/dev/null || true; sleep 1 }@@ -107,7 +112,13 @@ launch() {   cd "$PROJECT_DIR" || return 1   rotate_log   echo "[$(date -Is)] claude-rc: launching (name=$(rc_name), env=$(env_name))" >> "$LOG"-  setsid nohup claude rc --name "$(rc_name)" </dev/null >> "$LOG" 2>&1 &+  # STDIN MUST STAY OPEN. `claude rc` is a TUI that waits on a keypress ("space to show QR+  # code"); with </dev/null it connects, reads EOF, and exits within a second (the log shows+  # "Connected" five times, then the crash-loop guard marks it failed). A pipe that never+  # closes (sleep infinity) gives it a stdin with no data and no EOF, so it runs until killed.+  # The pipeline is wrapped in its own bash so `exec` keeps the pgrep pattern on the real+  # server process, not on the wrapper.+  setsid nohup bash -c 'sleep infinity | exec claude rc --name "$1"' _ "$(rc_name)" >> "$LOG" 2>&1 &   # crash-loop guard: remember launch times, keep the last hour's worth   local t; t="$(now)"   local hist; hist="$(st_get launches)"
package.json+3−3
@@ -1,6 +1,6 @@ {   "slug": "hook",-  "version": "1.3.0",+  "version": "1.3.1",   "type": "app",   "org": "adom",   "bundled": true,@@ -56,7 +56,7 @@       "mode": "0755"     }   ],-  "changelog": "1.3.0: add claude-rc, which keeps Claude Code Remote Control (`claude rc`) alive so a user can open new AI threads on their container from the Claude mobile app or claude.ai/code. It rides in adom/hook because it needs exactly what this package already owns: a UserPromptSubmit hook and a cron entry. Consent-first -- installing only wires the offer, and the AI asks the user once. Supervision differs by environment: a 2-minute cron watchdog on ah, and the prompt hook itself on hc, which has neither cron nor systemd. No dependency changes.",+  "changelog": "1.3.1: claude-rc keeps stdin open when launching `claude rc` (sleep infinity pipe). With </dev/null the server connected and exited within a second, five times, and the crash-loop guard marked it failed on every container. The watchdog's pgrep pattern also required a path prefix that a PATH launch never has, so it relaunched a live server and reported it as not running. Found on an Adom cloud container and an Adom Hydrogen WSL2 workspace, 2026-08-30. 1.3.0: add claude-rc, which keeps Claude Code Remote Control (`claude rc`) alive so a user can open new AI threads on their container from the Claude mobile app or claude.ai/code. It rides in adom/hook because it needs exactly what this package already owns: a UserPromptSubmit hook and a cron entry. Consent-first -- installing only wires the offer, and the AI asks the user once. Supervision differs by environment: a 2-minute cron watchdog on ah, and the prompt hook itself on hc, which has neither cron nor systemd. No dependency changes.",   "discovery_pitch": "Use when adom packages are behind or an update failed, and when the user asks about Claude Remote Control -- opening AI threads on this container from their phone or claude.ai/code.",   "sample_prompts": [     {@@ -72,4 +72,4 @@       "prompt": "are my adom packages current with the wiki?"     }   ]-}\ No newline at end of file+}
page.json+14−2
@@ -1,6 +1,6 @@ {   "slug": "hook",-  "version": "1.3.0",+  "version": "1.3.1",   "type": "app",   "org": "adom",   "bundled": true,@@ -50,7 +50,7 @@     "name": "Kyle Bergstedt",     "email": "[email protected]"   },-  "changelog": "1.3.0: add claude-rc, which keeps Claude Code Remote Control (`claude rc`) alive so a user can open new AI threads on their container from the Claude mobile app or claude.ai/code. It rides in adom/hook because it needs exactly what this package already owns: a UserPromptSubmit hook and a cron entry. Consent-first -- installing only wires the offer, and the AI asks the user once. Supervision differs by environment: a 2-minute cron watchdog on ah, and the prompt hook itself on hc, which has neither cron nor systemd. No dependency changes.",+  "changelog": "1.3.1: claude-rc keeps stdin open when launching `claude rc` (sleep infinity pipe). With </dev/null the server connected and exited within a second, five times, and the crash-loop guard marked it failed on every container. The watchdog's pgrep pattern also required a path prefix that a PATH launch never has, so it relaunched a live server and reported it as not running. Found on an Adom cloud container and an Adom Hydrogen WSL2 workspace, 2026-08-30. 1.3.0: add claude-rc, which keeps Claude Code Remote Control (`claude rc`) alive so a user can open new AI threads on their container from the Claude mobile app or claude.ai/code. It rides in adom/hook because it needs exactly what this package already owns: a UserPromptSubmit hook and a cron entry. Consent-first -- installing only wires the offer, and the AI asks the user once. Supervision differs by environment: a 2-minute cron watchdog on ah, and the prompt hook itself on hc, which has neither cron nor systemd. No dependency changes.",   "discovery_pitch": "Use when adom packages are behind or an update failed, and when the user asks about Claude Remote Control -- opening AI threads on this container from their phone or claude.ai/code.",   "sample_prompts": [     {@@ -65,5 +65,17 @@       "label": "Am I up to date?",       "prompt": "are my adom packages current with the wiki?"     }+  ],+  "managed_files": [+    {+      "src": "check-updates.sh",+      "dest": "~/.adom/hooks/adom-core-update.sh",+      "mode": "0755"+    },+    {+      "src": "claude-rc",+      "dest": "~/.local/bin/claude-rc",+      "mode": "0755"+    }   ] }\ No newline at end of file