Something went wrong. Try again.
Identities for entities did.bot
agent llm did
Something went wrong. Try again.
Shell
at claude/xray
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106# Sourced by the dev-*.sh scripts that need to replace a previous run.## The thing this exists to stop: `pkill -f "didbot-pds --port 3000"`# matches any process whose *arguments* contain that string. That includes# another developer's server, an editor with the command in a buffer, and — on# a bad day — the shell running the script, which is a `kill` that takes out# the thing doing the killing. It has happened.## A pidfile names one process. Before signalling it, /proc is consulted to# confirm the process is still the binary the file was written for: a pid is# reused, and a stale file must never be a licence to kill whatever inherited# its number.
# Where a service's pidfile lives, keyed by name and port so that two stacks on# one machine never collide._didbot_pidfile() { local base="${XDG_RUNTIME_DIR:-/tmp}/didbot" mkdir -p "$base" 2>/dev/null || true echo "$base/$1-$2.pid"}
# Whether a pid is alive and is still running the expected binary._didbot_is() { local pid="$1" binary="$2" [ -n "$pid" ] || return 1 kill -0 "$pid" 2>/dev/null || return 1 # The kernel's own answer, not a pattern over a rendered command line. # /proc/<pid>/exe is the binary that is actually executing. local exe exe="$(readlink "/proc/$pid/exe" 2>/dev/null)" || return 1 case "$exe" in *"/$binary") return 0 ;; *"/$binary (deleted)") return 0 ;; *) return 1 ;; esac}
# Stop a previous run of this service, if there is one, and claim the pidfile.## claim_port <service-name> <port> <binary-name>## Called before the build so that a port held by a previous run is released# early rather than after a minute of compiling.claim_port() { local name="$1" port="$2" binary="$3" local file previous file="$(_didbot_pidfile "$name" "$port")"
if [ -r "$file" ]; then previous="$(cat "$file" 2>/dev/null)" if _didbot_is "$previous" "$binary"; then printf '\033[1m%s\033[0m\n' "stopping the previous $name on port $port (pid $previous)" kill "$previous" 2>/dev/null || true # Give it a moment to release the port, then insist. local waited=0 while kill -0 "$previous" 2>/dev/null && [ "$waited" -lt 50 ]; do sleep 0.1 waited=$((waited + 1)) done kill -9 "$previous" 2>/dev/null || true fi rm -f "$file" fi
# This shell's pid, because every one of these scripts ends in `exec`: the # process that finally holds the port is this one, with a different # program running in it. echo "$$" > "$file"}
# Record the pid that actually holds a port, for a caller that starts the# service in the background instead of ending in `exec`.## record_pid <service-name> <port> <pid>## `claim_port` writes its own shell's pid, which is right only when that shell# becomes the server. A script that backgrounds several services is a different# process from all of them, so it says which is which here.record_pid() { echo "$3" > "$(_didbot_pidfile "$1" "$2")"}
# Drop a pidfile whose service this caller has just stopped.## forget_pid <service-name> <port>## The dev scripts leave theirs, and the note below says why. A caller that# picks a fresh port every run is the case that note does not cover: it never# reuses a file, so leaving them accumulates one per run forever.forget_pid() { rm -f "$(_didbot_pidfile "$1" "$2")"}
# A stale pidfile is expected, and is not cleaned up.## There used to be an `EXIT` trap here to remove it, and it never ran once:# every one of these scripts ends in `exec`, which replaces the shell with the# server and takes the trap with it. A trap that reads as if it tidies up and# does not is worse than no trap, because the next person to see a leftover# file goes looking for the bug in the wrong place.## It costs nothing to leave. `claim_port` reads `/proc/<pid>/exe` before it# signals anything, so a file naming a process that is gone — or one whose# number has since been reused by something else — is ignored and overwritten.# The file is a hint about who to ask, never a licence to kill.