Vendor the command set the menu and shell depend on

This commit is contained in:
2026-09-19 23:57:12 -04:00
parent 9501f2bb4d
commit c5434026a8
179 changed files with 12414 additions and 54 deletions
+77
View File
@@ -0,0 +1,77 @@
#!/bin/bash
# blob:summary=Watch for process crashes and offer an AI diagnosis
# blob:hidden=true
# systemd-coredump journals every core dump under a known MESSAGE_ID with
# structured COREDUMP_* fields, which carry more than the core filenames do.
set -uo pipefail
# See systemd.journal-fields(7).
readonly COREDUMP_MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1
# nf-md-robot_dead, escaped so this file reads without a Nerd Font.
readonly CRASH_GLYPH=$'\U000f16a1'
# Crash loops dump core repeatedly, so announce each program at most once a
# window.
readonly dedupe_seconds=${BLOB_CRASH_DEDUPE_SECONDS:-60}
# Extended regex of process names never worth announcing.
readonly ignore_pattern=${BLOB_CRASH_IGNORE:-}
declare -A last_notified
announce() {
local comm=$1 pid=$2 exe=$3 signal=$4
# The shell owns org.freedesktop.Notifications, so a shell crash takes the
# notification server down with it and a toast sent into that gap is lost.
# Wait for the restarted shell to claim the name again: the crash least
# likely to be delivered is the one most worth reporting.
blob-notification-wait || return 1
# Keeps the default "blob-action" app name, the only one shouldBypassDnd()
# lets through.
blob-notify-send \
--urgency critical \
--glyph "$CRASH_GLYPH" \
"Process crashed: $comm" \
"$signal from pid $pid"
}
# -n 0 so a restart does not re-announce crashes already dealt with.
journalctl -f -n 0 -o json "MESSAGE_ID=$COREDUMP_MESSAGE_ID" 2>/dev/null |
while IFS= read -r entry; do
IFS=$'\t' read -r uid comm pid exe signal < <(
jq -r '[(._UID // "-"),
(.COREDUMP_COMM // "-"),
(.COREDUMP_PID // "-"),
(.COREDUMP_EXE // "-"),
(.COREDUMP_SIGNAL_NAME // "-")] | @tsv' <<<"$entry" 2>/dev/null
)
[[ $pid =~ ^[0-9]+$ ]] || continue
# Only this user's crashes; a daemon dumping core is a sysadmin's problem.
[[ $uid =~ ^[0-9]+$ ]] || continue
((uid == UID)) || continue
# comm is truncated to 15 characters, so prefer the executable's basename.
name=$comm
[[ $exe == /* ]] && name=${exe##*/}
[[ -n $ignore_pattern && $name =~ $ignore_pattern ]] && continue
# Never announce our own machinery, or it notifies about itself.
[[ $name == blob-crash-* ]] && continue
now=$EPOCHSECONDS
(((now - ${last_notified[$name]:-0}) < dedupe_seconds)) && continue
# Only a delivered toast starts the dedupe window. A failed send that
# counted would suppress the rest of a crash loop for a minute, and
# `journalctl -n 0` never replays what was missed.
announce "$name" "$pid" "$exe" "$signal" && last_notified[$name]=$now
done