Files
devdesk/libexec/devdesk-notify-matrix
T
jaredandClaude Opus 5.5 be9b026a01
build-deb / Lint, test, package (push) Successful in 2m12s
build-deb / Deploy to CT 126 (push) Successful in 3s
build-deb / Notify on failure (push) Skipped
feat: v0.5.0 header, switcher, phone key bar, shared polling, Matrix "needs you"
- Header: no SSO chip ("Sign in again" only on expiry), state dot on the
  session chip, LIVE as a dot, ⋯ menu for text size/notifications/fullscreen,
  Panels badge for waiting sessions and alerts.
- Session switcher on the chip; bare URL reattaches the last session; + New
  opens the panel form with project folders.
- Notifications when other sessions start waiting; alerts polled with the
  panels closed; one tab polls for all tabs over BroadcastChannel.
- Sidebar: context bar per session instead of the Context panel; compact
  Repo/CI with "Ask Claude to fix CI"; legible labels.
- Phone: key bar, drawer with backdrop, visualViewport-aware layout, DOM
  renderer on touch, compact connection dot.
- devdesk-notify-matrix: one Matrix message per wait that lasts
  DEVDESK_MATRIX_DELAY seconds with nobody attached.

Closes #8
Closes #13
Closes #14
Closes #15
Closes #16
Closes #17
Closes #28

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 23:34:59 -04:00

42 lines
2.0 KiB
Bash
Executable File

#!/bin/bash
# devdesk-notify-matrix SESSION SINCE
#
# Started (detached) by devdesk-state-hook when a session starts waiting on you.
# After DEVDESK_MATRIX_DELAY seconds, if that same wait is still on and nobody is
# attached to the session (no browser tab, no SSH client), post one "Claude needs
# you" message to the hookshot webhook in DEVDESK_MATRIX_WEBHOOK_FILE (devdesk#28).
set -euo pipefail
# shellcheck source=libexec/devdesk-lib.sh
. "${DEVDESK_LIBEXEC:-/usr/lib/devdesk}/devdesk-lib.sh"
session=${1:-}
since=${2:-}
dd_valid_name "$session" || exit 0
[[ $since =~ ^[0-9]+$ ]] || exit 0
[ -r "$DEVDESK_MATRIX_WEBHOOK_FILE" ] || exit 0
sleep "$DEVDESK_MATRIX_DELAY"
state_file="$DEVDESK_STATUS_DIR/$session.json"
# Still the same wait? (Answering it moves the state on; a new wait has its own notifier.)
[ "$(jq -rM '"\(.state) \(.since)"' "$state_file" 2>/dev/null)" = "waiting $since" ] || exit 0
# Anyone looking at it already?
attached=$(dd_tmux list-sessions -F '#{session_name} #{session_attached}' 2>/dev/null |
awk -v s="$session" '$1 == s { print $2 }')
[ "${attached:-0}" = 0 ] || exit 0
message=$(jq -rM '.message // "Claude is waiting for your input"' "$state_file" 2>/dev/null)
url=""
[ -z "$DEVDESK_PUBLIC_URL" ] || url="${DEVDESK_PUBLIC_URL%/}/?arg=$session"
body=$(jq -cMn --arg s "$session" --arg m "$message" --arg u "$url" --arg h "$(hostname)" \
'{session: $s, message: $m, url: (if $u == "" then null else $u end), host: $h,
text: ("Claude needs you in " + $s + ": " + $m + (if $u == "" then "" else " — " + $u end))}')
# The webhook URL is a secret (anyone holding it can post to the room): pass it
# to curl on stdin, never on the command line.
# shellcheck disable=SC1003 # tr deletes whitespace, quotes and backslashes from the URL
webhook=$(tr -d '[:space:]"\\' <"$DEVDESK_MATRIX_WEBHOOK_FILE")
printf 'url = "%s"\n' "$webhook" |
curl -fsS --max-time 10 --retry 2 -K - -H 'Content-Type: application/json' --data-binary "$body" >/dev/null