sync: auto-sync from GURU-BEAST-ROG at 2026-06-02 10:44:23
Author: Mike Swanson Machine: GURU-BEAST-ROG Timestamp: 2026-06-02 10:44:23
This commit is contained in:
@@ -73,6 +73,23 @@ drive the human's interactive session.
|
||||
|
||||
---
|
||||
|
||||
## Pricing — Always Verify, Never Guess
|
||||
|
||||
**MANDATORY:** Before presenting any cost to Mike, Howard, or a client, verify current pricing
|
||||
via live web lookup. Never estimate or recall costs from training data — hardware prices,
|
||||
software licensing, and labor rates change constantly.
|
||||
|
||||
Rules:
|
||||
- Any dollar amount for hardware, parts, software, or services requires a real-time lookup
|
||||
before being stated.
|
||||
- Use WebFetch / WebSearch first. Fall back to headless Chrome if bot-blocked.
|
||||
- Cite the source and date: `[$X.XX — Amazon, 2026-06-02]`
|
||||
- If you cannot reach a pricing source, say so explicitly — do NOT substitute a guess.
|
||||
- Applies to all estimate types: parts, repair quotes, hardware refreshes, software licensing,
|
||||
labor, and third-party services.
|
||||
|
||||
---
|
||||
|
||||
## Task Loop
|
||||
|
||||
For every request, work this loop:
|
||||
@@ -86,13 +103,41 @@ For every request, work this loop:
|
||||
4. **Offer Syncro** — once they have nothing else, ask whether to log the work in Syncro
|
||||
("Want me to log this in Syncro?"). If yes, invoke `/syncro` to create or update the ticket.
|
||||
5. **Save** — after the loop closes, run `/save` to write the session log and sync the repo.
|
||||
6. **Kill the thread** — after `/save` completes successfully, delete the thread:
|
||||
```bash
|
||||
bash C:/Users/guru/ClaudeTools/projects/discord-bot/scripts/delete-thread.sh <Thread ID>
|
||||
```
|
||||
The Thread ID is in every `[DISCORD_CONTEXT]` block as `Thread ID: <id>`. Do not delete
|
||||
if `/save` failed or errored. Do not post a closing message — the deletion is immediate.
|
||||
|
||||
---
|
||||
|
||||
## Thread Lifecycle — Auto-Delete on Completion
|
||||
|
||||
Every `[DISCORD_CONTEXT]` block now includes `Thread ID: <id>` (injected by the bot after
|
||||
the thread is resolved or created). This ID is what you pass to the delete script.
|
||||
|
||||
**When to delete:** Only after step 6 of the Task Loop — `/save` succeeded, session log
|
||||
committed and pushed. The thread is the conversation record; don't kill it before the log lands.
|
||||
|
||||
**When NOT to delete:**
|
||||
- `/save` failed or sync errored
|
||||
- The user said "yes" to continuing (open follow-up items remain)
|
||||
- The thread is an ongoing informational channel, not a single-task session
|
||||
|
||||
**Script:**
|
||||
```bash
|
||||
bash C:/Users/guru/ClaudeTools/projects/discord-bot/scripts/delete-thread.sh <Thread ID>
|
||||
```
|
||||
Source: `projects/discord-bot/scripts/delete-thread.sh` — reads bot token from `.env`, calls
|
||||
`DELETE /channels/{id}` on the Discord API. Exits 0 on HTTP 200/204, 1 on error.
|
||||
|
||||
---
|
||||
|
||||
## Who Is Asking: Discord User Identity
|
||||
|
||||
Every message is prefixed with a `[DISCORD_CONTEXT]` block containing the sender's Discord
|
||||
username, display name, and user ID. Always read this block to determine who is asking.
|
||||
username, display name, user ID, and Thread ID. Always read this block to determine who is asking.
|
||||
|
||||
### Known Team Members — Full Access
|
||||
|
||||
|
||||
@@ -41,7 +41,18 @@ class MessageHandler:
|
||||
await message.reply("Hey! How can I help?")
|
||||
return
|
||||
|
||||
# Resolve or create the thread first so we can include its ID in context.
|
||||
if isinstance(message.channel, discord.Thread):
|
||||
thread = message.channel
|
||||
else:
|
||||
name = self._thread_name(user_text) if user_text else "Attachment"
|
||||
thread = await message.create_thread(
|
||||
name=name,
|
||||
auto_archive_duration=1440,
|
||||
)
|
||||
|
||||
# Build caller-identity header so the agent always knows who is asking.
|
||||
# Thread ID is included so the agent can delete the thread on completion.
|
||||
author = message.author
|
||||
display = getattr(author, "display_name", author.name)
|
||||
guild_name = message.guild.name if message.guild else "DM"
|
||||
@@ -51,20 +62,11 @@ class MessageHandler:
|
||||
f"User: @{author.name}"
|
||||
+ (f" (display: {display})" if display != author.name else "")
|
||||
+ f" | ID: {author.id}\n"
|
||||
f"Channel: #{channel_name} | Guild: {guild_name}\n"
|
||||
f"Channel: #{channel_name} | Thread ID: {thread.id} | Guild: {guild_name}\n"
|
||||
"[/DISCORD_CONTEXT]\n\n"
|
||||
)
|
||||
content = (discord_ctx + user_text).strip()
|
||||
|
||||
if isinstance(message.channel, discord.Thread):
|
||||
thread = message.channel
|
||||
else:
|
||||
name = self._thread_name(user_text) if user_text else "Attachment"
|
||||
thread = await message.create_thread(
|
||||
name=name,
|
||||
auto_archive_duration=1440,
|
||||
)
|
||||
|
||||
attachment_paths = await self._download_attachments(message, thread.id)
|
||||
if attachment_paths:
|
||||
lines = "\n".join(f"- {p}" for p in attachment_paths)
|
||||
|
||||
56
projects/discord-bot/scripts/delete-thread.sh
Normal file
56
projects/discord-bot/scripts/delete-thread.sh
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
# delete-thread.sh <thread_id>
|
||||
#
|
||||
# Deletes a Discord thread (channel) via the Discord REST API.
|
||||
# Reads the bot token from projects/discord-bot/.env (DISCORD_TOKEN=...).
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 — deleted (HTTP 200 or 204)
|
||||
# 1 — bad args, token not found, or API error
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
THREAD_ID="${1:-}"
|
||||
if [ -z "$THREAD_ID" ]; then
|
||||
echo "[ERROR] Usage: delete-thread.sh <thread_id>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ENV_FILE="$SCRIPT_DIR/../.env"
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "[ERROR] .env not found at $ENV_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract token — handles quoted and unquoted values, ignores inline comments
|
||||
DISCORD_TOKEN=$(grep '^DISCORD_TOKEN=' "$ENV_FILE" \
|
||||
| head -1 \
|
||||
| sed 's/^DISCORD_TOKEN=//' \
|
||||
| sed "s/[\"']//g" \
|
||||
| sed 's/#.*//' \
|
||||
| tr -d '[:space:]')
|
||||
|
||||
if [ -z "$DISCORD_TOKEN" ]; then
|
||||
echo "[ERROR] DISCORD_TOKEN not found or empty in $ENV_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RESP=$(curl -s -o /tmp/discord_delete_resp.txt -w "%{http_code}" \
|
||||
-X DELETE \
|
||||
"https://discord.com/api/v10/channels/${THREAD_ID}" \
|
||||
-H "Authorization: Bot ${DISCORD_TOKEN}" \
|
||||
-H "Content-Type: application/json")
|
||||
|
||||
HTTP_CODE="$RESP"
|
||||
BODY=$(cat /tmp/discord_delete_resp.txt 2>/dev/null || echo "")
|
||||
rm -f /tmp/discord_delete_resp.txt
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "204" ]; then
|
||||
echo "[OK] Thread ${THREAD_ID} deleted (HTTP ${HTTP_CODE})"
|
||||
exit 0
|
||||
else
|
||||
echo "[ERROR] Delete failed: HTTP ${HTTP_CODE} — ${BODY}" >&2
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user