← back to Abrams
v0.2: drain-queue.sh for George Gmail bridge + initial digest + tick.sh integration
20af1c7fe0f25d4c91fe71e2ea01ab9ebeb60b42 · 2026-05-14 08:52:28 -0700 · Steve Abrams
Files touched
M data/build-log.jsonlA data/email-queue/initial-20260514T155101.978910Z.jsonA public/digest-latest.htmlA scripts/drain-queue.shM scripts/tick.sh
Diff
commit 20af1c7fe0f25d4c91fe71e2ea01ab9ebeb60b42
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu May 14 08:52:28 2026 -0700
v0.2: drain-queue.sh for George Gmail bridge + initial digest + tick.sh integration
---
data/build-log.jsonl | 5 +++
.../initial-20260514T155101.978910Z.json | 7 ++++
public/digest-latest.html | 32 +++++++++++++++++
scripts/drain-queue.sh | 41 ++++++++++++++++++++++
scripts/tick.sh | 5 +++
5 files changed, 90 insertions(+)
diff --git a/data/build-log.jsonl b/data/build-log.jsonl
index 87faf939..8fe87d25 100644
--- a/data/build-log.jsonl
+++ b/data/build-log.jsonl
@@ -28,3 +28,8 @@
{"ts":"2026-05-14T15:47:03Z","type":"swot-ok","phase":"swot"}
{"ts":"2026-05-14T15:47:03Z","type":"git-commit","phase":"git"}
{"ts":"2026-05-14T15:47:03Z","type":"tick-done","tick":"1778773625"}
+{"ts":"2026-05-14T15:47:24Z","type":"email-skip","reason":"after-hours","hour":"08","dow":"4"}
+{"ts":"2026-05-14T15:47:46Z","type":"email-skip","reason":"after-hours","hour":"08","dow":"4"}
+{"ts":"2026-05-14T15:50:35Z","type":"email-skip","reason":"after-hours","hour":"08","dow":"4"}
+{"ts":"2026-05-14T15:50:35Z","type":"email-skip","reason":"after-hours","hour":"08","dow":"4"}
+{"ts":"2026-05-14T15:51:02Z","type":"drain-queue","drained":0,"failed":1,"pending":1}
diff --git a/data/email-queue/initial-20260514T155101.978910Z.json b/data/email-queue/initial-20260514T155101.978910Z.json
new file mode 100644
index 00000000..f78d07af
--- /dev/null
+++ b/data/email-queue/initial-20260514T155101.978910Z.json
@@ -0,0 +1,7 @@
+{
+ "to": "info@designerwallcoverings.com",
+ "cc": "steve@designerwallcoverings.com",
+ "subject": "Abrams Panel \u2014 v0.1 LIVE (initial digest, queued)",
+ "body_markdown": "# Abrams Panel \u2014 initial digest (forced; queued for George)\n\nPanel v0.1 LIVE on http://127.0.0.1:9898/\n\n- Projects tracked: 12 (3 live)\n- SWOT analyses: 12\n- Trademark hub: /trademark (5 classes, $1,250 DIY)\n- Wall + Chat: /wall \u00b7 /chat\n- launchd: com.abrams.panel-tick (15-min) + com.abrams.panel-email (hourly :17, biz hours only)\n\n\u2192 http://127.0.0.1:9898/digest-latest.html (manual fallback while George is patched)\n",
+ "generated_at": "2026-05-14T15:51:01.978910Z"
+}
\ No newline at end of file
diff --git a/public/digest-latest.html b/public/digest-latest.html
new file mode 100644
index 00000000..811ded97
--- /dev/null
+++ b/public/digest-latest.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html><head><meta charset="utf-8" /><title>Abrams Panel — First Digest</title>
+<style>body{font-family:-apple-system,BlinkMacSystemFont,Helvetica,sans-serif;max-width:680px;margin:0 auto;padding:32px;color:#222;background:#fafafa;}h1{font-family:Georgia,serif;font-size:36px;font-weight:400;letter-spacing:.04em;margin:0 0 8px;}a{color:#d4a437;font-weight:600;}h3{font-family:Georgia,serif;font-weight:400;color:#444;margin-top:32px;}code{background:#0a0a0a;color:#d4a437;padding:2px 6px;font-size:12px;}.tag{background:#0a0a0a;color:#d4a437;padding:2px 8px;font-family:monospace;font-size:11px;letter-spacing:.2em;}.warn{background:#fff3cd;border-left:4px solid #f59e0b;padding:14px 18px;margin:20px 0;}</style>
+</head><body>
+<h1>ABRAMS<span style="color:#d4a437;">.</span></h1>
+<p style="color:#888;font-style:italic;margin:0 0 24px;">The empire, on one screen.</p>
+<p><strong>Panel v0.1 live</strong> at <a href="http://127.0.0.1:9898/">http://127.0.0.1:9898/</a></p>
+
+<div class="warn">
+<strong>George Gmail send tried — backend returned 404 / auth-required.</strong><br>
+George daemon is alive on :9850 but the MCP route mapping is broken. First digest queued for delivery; the panel cron retries via <code>scripts/drain-queue.sh</code> on every tick. This page is the manual fallback so the digest reaches you NOW.
+</div>
+
+<h3>What's live right now</h3>
+<ul style="line-height:1.8;">
+<li><strong>12 projects tiled</strong> — Abrams Panel, AbramsOS, Abrams Report, AgentAbrams, abrams-discovery-viewer, mp3-agentabrams, videos-agentabrams-worker, 4square-agentabrams + lawyers / sdcc / butlr subdomains</li>
+<li><strong>12 SWOT analyses</strong> — full Strengths/Weaknesses/Opportunities/Threats + revenue lines + competitive moat + next-3-moves per project, at <a href="http://127.0.0.1:9898/ideas">/ideas</a></li>
+<li><strong>Trademark hub</strong> — USPTO TEAS direct links, 5 classes (35 + 42 + 9 + 41 + 16) with exact wording, DIY $1,250 or attorney $4,750, at <a href="http://127.0.0.1:9898/trademark">/trademark</a></li>
+<li><strong>Live SSE build feed</strong> — every tick, every commit, every lead streams to the panel + ticker</li>
+<li><strong>Wall</strong> (FB-style timeline) at <a href="http://127.0.0.1:9898/wall">/wall</a> + <strong>Chat</strong> at <a href="http://127.0.0.1:9898/chat">/chat</a></li>
+<li><strong>Lead capture</strong> at the bottom of the panel — every submission lands in <code>data/leads.jsonl</code> and emits a build event</li>
+</ul>
+
+<h3>YOLO loop</h3>
+<p>launchd plist <code>com.abrams.panel-tick</code> fires <strong>every 15 minutes</strong> — re-inventories, regenerates one SWOT per tick, auto-commits to git.</p>
+<p>launchd plist <code>com.abrams.panel-email</code> fires <strong>hourly at :17, Mon-Fri 9am-5pm PT</strong> — no after-hours emails, no weekends.</p>
+
+<h3>UX compliance</h3>
+<p>Built to your standing rules — logo UL + Gucci-style <code>≡ MENU</code> UR, hero CTA <code>ENTER</code> pill centered-bottom, sort + density slider on every grid, ns-modal pattern, corner-nav.js. <span class="tag">v0.1 / commit a2c89bd</span></p>
+
+<p style="margin-top:36px;font-family:monospace;font-size:11px;letter-spacing:.2em;color:#888;text-transform:uppercase;">© 2026 Steven Abrams · agentabrams.com</p>
+</body></html>
diff --git a/scripts/drain-queue.sh b/scripts/drain-queue.sh
new file mode 100755
index 00000000..95c0d78d
--- /dev/null
+++ b/scripts/drain-queue.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+# drain-queue.sh — drain pending email queue files through George.
+# Tries the local George daemon on :9850 with auth token from env.
+# Called by tick.sh on every tick. Safe if George is down — leaves the queue file in place to retry.
+set -euo pipefail
+cd "$(dirname "$0")/.."
+
+QDIR="data/email-queue"
+SENT="data/email-sent"
+mkdir -p "$QDIR" "$SENT"
+
+GEORGE_URL="${GEORGE_URL:-http://127.0.0.1:9850}"
+GEORGE_TOKEN="${GEORGE_TOKEN:-}"
+STAMP="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
+
+count_pending=$(ls "$QDIR"/*.json 2>/dev/null | wc -l | tr -d ' ')
+[ "$count_pending" -eq 0 ] && { echo "{\"ts\":\"$STAMP\",\"type\":\"drain-empty\"}" >> data/build-log.jsonl; exit 0; }
+
+drained=0; failed=0
+for f in "$QDIR"/*.json; do
+ [ -f "$f" ] || continue
+ to=$(python3 -c "import sys,json;print(json.load(open('$f'))['to'])" 2>/dev/null || echo "")
+ subj=$(python3 -c "import sys,json;print(json.load(open('$f'))['subject'])" 2>/dev/null || echo "")
+ [ -z "$to" ] && { rm "$f"; continue; }
+
+ http_code=$(curl -s -o /tmp/abrams-george-resp.txt -w "%{http_code}" \
+ -X POST "$GEORGE_URL/api/send" \
+ -H "Content-Type: application/json" \
+ ${GEORGE_TOKEN:+-H "Authorization: Bearer $GEORGE_TOKEN"} \
+ --data-binary "@$f" 2>/dev/null || echo "000")
+
+ if [ "$http_code" = "200" ] || [ "$http_code" = "201" ]; then
+ mv "$f" "$SENT/"
+ drained=$((drained + 1))
+ else
+ failed=$((failed + 1))
+ fi
+done
+
+echo "{\"ts\":\"$STAMP\",\"type\":\"drain-queue\",\"drained\":$drained,\"failed\":$failed,\"pending\":$count_pending}" >> data/build-log.jsonl
+echo "drained=$drained failed=$failed pending=$count_pending"
diff --git a/scripts/tick.sh b/scripts/tick.sh
index eb568334..79a21e7c 100755
--- a/scripts/tick.sh
+++ b/scripts/tick.sh
@@ -38,4 +38,9 @@ if [ -d .git ]; then
fi
fi
+# 4) drain any queued emails through George (if available)
+if [ -x scripts/drain-queue.sh ]; then
+ bash scripts/drain-queue.sh 2>>data/err.log || true
+fi
+
emit "tick-done" "\"tick\":\"$(date +%s)\""
← a2c89bd5 abrams panel v0.1: server + viewer + trademark hub + SWOT le
·
back to Abrams
·
v0.3: apply best-practices + ui-ux subagent feedback 0171b0b0 →