From ead30520e561abfce3d8bcdabb2bbd30b6f5a39d Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Tue, 7 Jul 2026 07:23:39 -0700 Subject: [PATCH] sync: auto-sync from HOWARD-HOME at 2026-07-07 07:23:12 Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-07-07 07:23:12 --- .claude/memory/MEMORY.md | 1 + .../memory/feedback_discord_read_replies.md | 26 ++++++++++ .claude/scripts/discord-dm.sh | 41 +++++++++++++-- .claude/skills/discord-dm/SKILL.md | 19 ++++++- projects/gps-rmm-audit/needs-screenconnect.md | 52 +++++++++---------- 5 files changed, 108 insertions(+), 31 deletions(-) create mode 100644 .claude/memory/feedback_discord_read_replies.md diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index 28f82801..09d80883 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -29,6 +29,7 @@ - [TickTick Integration](reference_ticktick_integration.md) — OAuth API integration, MCP server, SOPS vault creds, project/task CRUD. - [Client Docs Structure](reference_client_docs_structure.md) — clients//docs/ layout (overview, network, servers, cloud, security, rmm). Template: clients/_client_template/. - [Client Wi-Fi Inventory](reference_client_wifi_inventory.md) — Building a fleet Wi-Fi list to connect onsite without asking. Passwords → vault `clients//wifi.sops.yaml` (`credentials._ssid/_password`); readable index → `wiki/reference/client-wifi.md`. `/wifi` importer deferred (structure-only 2026-07-06). +- [Discord read replies](feedback_discord_read_replies.md) — Discord DM replies don't come through coord/repo sync. Use `discord-dm.sh read ` to see if mike/winter/rob actually answered before assuming silence. - [MSP Audit Scripts](reference_msp_audit_scripts.md) — server_audit.ps1 / workstation_audit.ps1 at projects/msp-tools/msp-audit-scripts/. - [Pluto Build Server](reference_pluto_build_server.md) — Windows build VM: hostname PLUTO = Unraid VM "Claude-Builder" = 172.16.3.36 (all the same box). MSVC + WiX + Azure Trusted Signing. Drive via /rmm (agent enrolls as PLUTO) when SSH key isn't authorized. - [Coord /messages API shape](reference_coord_messages_api_shape.md) — GET /api/coord/messages returns {total,skip,limit,messages[]} NOT a bare array; parse .messages[], strip control chars, read flag may be null. diff --git a/.claude/memory/feedback_discord_read_replies.md b/.claude/memory/feedback_discord_read_replies.md new file mode 100644 index 00000000..aeb354b9 --- /dev/null +++ b/.claude/memory/feedback_discord_read_replies.md @@ -0,0 +1,26 @@ +--- +name: feedback_discord_read_replies +description: Discord DM replies are invisible to coord/repo sync — use `discord-dm.sh read ` to see if mike/winter/rob actually answered. +metadata: + type: feedback +--- + +When we DM someone via the `discord-dm` skill and wait on an answer, their reply does NOT +come through coord messages or repo sync — those channels never carry Discord replies. Before +telling the user "no reply yet / they didn't answer," READ the DM channel: + +```bash +bash .claude/scripts/discord-dm.sh read mike 10 # last 10 in the mike DM +bash .claude/scripts/discord-dm.sh read #dev-alerts # a channel +``` + +Output is oldest-first; lines marked `>>>` are from THEM (replies), indented lines are us. + +**Why:** the bot participates in every DM channel it opened, so `GET /channels//messages` +returns full content — the Message Content privileged intent only gates gateway events, not this +REST fetch. Before adding `read` (2026-07-07, Howard flagged it) the wrapper was send-only, so +replies from mike/winter were silently missed. + +**How to apply:** after DMing a question to mike/winter/rob, `read` that user to check for their +answer instead of assuming silence. Related: [[reference_community_forum]] is a different channel; +this is Discord DMs/channels via [[discord-dm]] (`.claude/scripts/discord-dm.sh`). diff --git a/.claude/scripts/discord-dm.sh b/.claude/scripts/discord-dm.sh index a37edcc4..08a64fab 100644 --- a/.claude/scripts/discord-dm.sh +++ b/.claude/scripts/discord-dm.sh @@ -6,6 +6,7 @@ # Usage: # discord-dm.sh "message text" # echo "message text" | discord-dm.sh +# discord-dm.sh read [limit] # READ recent messages — SEE replies (default 15) # discord-dm.sh list # show known users + channels # # is one of: @@ -51,11 +52,29 @@ if [ -z "$RECIPIENT" ] || [ "$RECIPIENT" = "-h" ] || [ "$RECIPIENT" = "--help" ] sed -n '2,30p' "$0"; exit 1 fi if [ "$RECIPIENT" = "list" ]; then print_dir; exit 0; fi + +# --- read mode: fetch recent messages so we can SEE replies (mike/winter/etc.). +# `discord-dm.sh read [limit]` — reuses the recipient resolution, +# token, and DM-channel-open below, then prints history instead of sending. The +# bot participates in each DM channel it opened, so REST history returns full +# content (the Message Content intent only gates gateway events, not this fetch). +ACTION=send +if [ "$RECIPIENT" = "read" ] || [ "$RECIPIENT" = "inbox" ]; then + ACTION=read; shift + RECIPIENT="${1:-}" + [ -z "$RECIPIENT" ] && { echo "[ERROR] usage: discord-dm.sh read [limit]" >&2; exit 1; } +fi shift -# --- message (remaining args, else stdin) --- -if [ "$#" -gt 0 ]; then MSG="$*"; elif [ ! -t 0 ]; then MSG="$(cat)"; else MSG=""; fi -if [ -z "$MSG" ]; then echo "[ERROR] empty message — nothing sent" >&2; exit 1; fi +# --- message (send) or limit (read) --- +if [ "$ACTION" = "read" ]; then + READ_LIMIT="${1:-15}" + printf '%s' "$READ_LIMIT" | grep -qE '^[0-9]+$' || READ_LIMIT=15 + [ "$READ_LIMIT" -gt 100 ] && READ_LIMIT=100 +else + if [ "$#" -gt 0 ]; then MSG="$*"; elif [ ! -t 0 ]; then MSG="$(cat)"; else MSG=""; fi + if [ -z "$MSG" ]; then echo "[ERROR] empty message — nothing sent" >&2; exit 1; fi +fi # --- resolve recipient -> mode (dm|channel) + target id --- MODE=""; TARGET=""; LABEL="" @@ -99,6 +118,22 @@ if [ "$MODE" = "dm" ]; then TARGET="$CHID" fi +# --- read mode: fetch + print recent messages, then exit (no send) --- +if [ "$ACTION" = "read" ]; then + MSGS="$(curl -s -m 20 "${auth[@]}" "$API/channels/${TARGET}/messages?limit=${READ_LIMIT}")" + if ! printf '%s' "$MSGS" | jq -e 'type=="array"' >/dev/null 2>&1; then + echo "[ERROR] could not read $LABEL: $(printf '%s' "$MSGS" | head -c 200)" >&2 + bash "$ROOT/.claude/scripts/log-skill-error.sh" "discord-dm" "read history failed for $LABEL" --context "resp=$(printf '%s' "$MSGS" | head -c 80)" >/dev/null 2>&1 + exit 3 + fi + echo "[OK] discord-dm: last ${READ_LIMIT} message(s) in ${LABEL} (oldest first; '>>>' = reply from them, ' ' = us):" + printf '%s' "$MSGS" | jq -r 'reverse[] | + ((if (.author.bot // false) then " " else ">>> " end) + + (.timestamp[0:16]) + " " + .author.username + ": " + + ((.content // "") | gsub("\n";" ")))' + exit 0 +fi + # --- chunk: Discord caps content at 2000 chars (code 50035 on overflow). # This tool's job is delivering LONG content intact, so split into <=1900-char # pieces (preferring newline boundaries) and send them in order — no markers diff --git a/.claude/skills/discord-dm/SKILL.md b/.claude/skills/discord-dm/SKILL.md index ddae4fec..3695b2ab 100644 --- a/.claude/skills/discord-dm/SKILL.md +++ b/.claude/skills/discord-dm/SKILL.md @@ -1,6 +1,6 @@ --- name: discord-dm -description: "Send a Discord message to an org member DM or team channel via the ClaudeTools bot - copy-paste-friendly delivery of links/commands the terminal would mangle; address people by name (mike/howard/rob/winter). Triggers: DM in discord, send that link to my discord, ping ." +description: "Send OR read Discord messages to/from an org member DM or team channel via the ClaudeTools bot - copy-paste-friendly delivery of links/commands the terminal would mangle, and READ replies (coord/repo sync does not carry Discord answers); address people by name (mike/howard/rob/winter). Triggers: DM in discord, send that link to my discord, ping , did reply/answer, read discord replies, check discord DMs." --- # discord-dm — direct Discord messaging to the org @@ -27,9 +27,26 @@ DMs** and deliberate channel posts. ```bash bash .claude/scripts/discord-dm.sh "message text" echo "message text" | bash .claude/scripts/discord-dm.sh +bash .claude/scripts/discord-dm.sh read [limit] # READ recent messages — SEE replies (default 15) bash .claude/scripts/discord-dm.sh list # print known users + channels ``` +## Reading replies (`read`) + +Sends are one-way, but people **answer** — always `read` before assuming silence. The bot +participates in every DM channel it opened, so `GET /channels//messages` returns full +content (the Message Content privileged intent only gates *gateway* events, not this REST +fetch). Works for users and channels: + +```bash +bash .claude/scripts/discord-dm.sh read mike 10 # last 10 in the mike DM +bash .claude/scripts/discord-dm.sh read #dev-alerts # last 15 in #dev-alerts +``` + +Output is oldest-first; lines from **them** are marked `>>>`, lines from us are indented. +After DMing someone a question, `read` that user to check for their answer — coord/repo sync +does NOT carry Discord replies, so this is the only way to see them. + ``: | Form | Effect | diff --git a/projects/gps-rmm-audit/needs-screenconnect.md b/projects/gps-rmm-audit/needs-screenconnect.md index 54b9837b..a5186f43 100644 --- a/projects/gps-rmm-audit/needs-screenconnect.md +++ b/projects/gps-rmm-audit/needs-screenconnect.md @@ -3,29 +3,27 @@ Online = ActiveConnections ProcessType==2 (guest agent connected). Recency = GuestInfoUpdateTime. Rebuilt 2026-07-04. Staging installer pushed to all ONLINE machines (land in Staging -> reassign-staging.py). -## ONLINE now (1) -- IMC-PRINTSERVER [Instrumental Music Center] (1d) +## ONLINE now (2) +- IMC-PRINTSERVER [Instrumental Music Center] (2d) +- WILLCOXDOTADMIN [Reliant Well Drilling and Pump Corporate] (0d) -## active <=14d (13) -- KAT1 [Business Services of Tucson LLC] (0d) -- HSM-CATHY [Horseshoe Management] (3d) -- IMC-M-EDSERVICE [Instrumental Music Center] (4d) +## active <=14d (10) +- KAT1 [Business Services of Tucson LLC] (1d) +- IMC-M-EDSERVICE [Instrumental Music Center] (0d) - LAPTOP-PNVA9G51 [Instrumental Music Center] (6d) -- REPAIRADMIN [Instrumental Music Center] (3d) -- PLS-SERVER [PUTT LAND SURVEYING, INC.] (9d) -- LAPTOP-73UDDTTK [Pro-Tech Services] (3d) -- WILLCOXDOTADMIN [Reliant Well Drilling and Pump Corporate] (3d) -- DESKTOP-ARNPE1U [Safesite] (3d) -- DESKTOP-V3H99FC [Safesite] (3d) +- REPAIRADMIN [Instrumental Music Center] (4d) +- PLS-SERVER [PUTT LAND SURVEYING, INC.] (10d) +- DESKTOP-ARNPE1U [Safesite] (4d) +- DESKTOP-V3H99FC [Safesite] (4d) - DESKTOP-V9F9L23 [Safesite] (0d) -- JEREE [Stamback Septic] (3d) +- JEREE [Stamback Septic] (4d) - DESKTOP-6HT5SJ9 [The Marc Group] (0d) ## stale 15-45d (4) -- GND-L-3 [Grabb & Durando Law Office] (22d) -- DESKTOP-KRHQ5TS [Instrumental Music Center] (17d) +- GND-L-3 [Grabb & Durando Law Office] (23d) +- DESKTOP-KRHQ5TS [Instrumental Music Center] (18d) - RWD-ALLENDESKTO [Reliant Well Drilling and Pump Corporate] (20d) -- DESKTOP-FMDIK0Q [Safesite] (44d) +- DESKTOP-FMDIK0Q [Safesite] (45d) ## dead/no-session (58) - DESKTOP-SUFJR0J [Bill Tedards] (no SC) @@ -40,22 +38,22 @@ Rebuilt 2026-07-04. Staging installer pushed to all ONLINE machines (land in Sta - Sheila’s MacBook Pro [Heieck, Sheila] (no SC) - HSM-RANDI [Horseshoe Management] (no SC) - HSM-SURFACE [Horseshoe Management] (no SC) -- DESKTOP-JQ0D38J [Instrumental Music Center] (107d) -- DESKTOP-URV3UGR [Instrumental Music Center] (81d) -- IMC-EVENTS [Instrumental Music Center] (112d) +- DESKTOP-JQ0D38J [Instrumental Music Center] (108d) +- DESKTOP-URV3UGR [Instrumental Music Center] (82d) +- IMC-EVENTS [Instrumental Music Center] (113d) - IMC-L1-GRAPHICS [Instrumental Music Center] (no SC) - PHIL [Instrumental Music Center] (no SC) -- PHIL2021LAPTOP [Instrumental Music Center] (143d) -- PURCHASINGCOMP [Instrumental Music Center] (81d) +- PHIL2021LAPTOP [Instrumental Music Center] (144d) +- PURCHASINGCOMP [Instrumental Music Center] (82d) - LHLH [Little Hearts Little Hands] (no SC) - WIN-KNVO6MUMMEM [Little Hearts Little Hands] (no SC) - CPC-chris-UZR6E [MVAN Enterprises Inc] (no SC) - DESKTOP-I7504C5 [MVAN Enterprises Inc] (no SC) - June’s MacBook Pro [MVAN Enterprises Inc] (no SC) -- MITCH-LAPTOP [MVAN Enterprises Inc] (140d) +- MITCH-LAPTOP [MVAN Enterprises Inc] (141d) - DESKTOP-3VPT017 [Mineralogical Record] (no SC) - DESKTOP-9QHSCIT [Mineralogical Record] (no SC) -- DESKTOP-S1HPLDF [Multicultural Counseling Center] (66d) +- DESKTOP-S1HPLDF [Multicultural Counseling Center] (67d) - PLS-FOUR [PUTT LAND SURVEYING, INC.] (no SC) - PLS-FRONT [PUTT LAND SURVEYING, INC.] (no SC) - PLS-LAPTOP [PUTT LAND SURVEYING, INC.] (no SC) @@ -72,10 +70,10 @@ Rebuilt 2026-07-04. Staging installer pushed to all ONLINE machines (land in Sta - RELIANT-L01 [Reliant Well Drilling and Pump Corporate] (no SC) - RELIANT-L02 [Reliant Well Drilling and Pump Corporate] (no SC) - RELIANT-L03 [Reliant Well Drilling and Pump Corporate] (no SC) -- RWD-ALANLAPTOP [Reliant Well Drilling and Pump Corporate] (128d) +- RWD-ALANLAPTOP [Reliant Well Drilling and Pump Corporate] (129d) - WILCOXADMIN [Reliant Well Drilling and Pump Corporate] (no SC) -- 1225-LENOVO-E16 [Safesite] (51d) -- DESKTOP-QAR6D04 [Safesite] (144d) +- 1225-LENOVO-E16 [Safesite] (52d) +- DESKTOP-QAR6D04 [Safesite] (145d) - DEREK-LAPTOP [Stamback Septic] (no SC) - DESKTOP-1BS5JL4 [Stamback Septic] (no SC) - DESKTOP-JVLQQIJ [Stamback Septic] (no SC) @@ -83,6 +81,6 @@ Rebuilt 2026-07-04. Staging installer pushed to all ONLINE machines (land in Sta - STAMBACK-JBECK [Stamback Septic] (no SC) - STAMBACK-NEW06 [Stamback Septic] (no SC) - STAMBACK-NEW06 [Stamback Septic] (no SC) -- LAPTOP-JMUNGO [The Marc Group] (56d) +- LAPTOP-JMUNGO [The Marc Group] (57d) - DESKTOP-SRUOH4R [The Prairie Schooner] (no SC) - DESKTOP-TS1P9MT [The Prairie Schooner] (no SC)