Files
hermes-agent/optional-skills/software-development/pr-lens/references/example.graph.json
T
teknium1 d7a56474fc feat(skills): pr-lens — animated architecture/data-flow diagrams for PRs (port of coldteadotai/pr-lens, 1.1k-star MIT)
Ports the pr-lens agent skill: represent a diff or subsystem as one
graph.json document and render it as animated SVG diagrams via the MIT
npx CLI (@coldtea/pr-lens-cli), with optional opt-in publishing to a
shareable canvas link.

Why: PR review and architecture explanation keep producing hand-drawn
Mermaid; this gives validated, animated, drill-down diagrams with a
deterministic document format. Upstream created Aug 20, 1.1k stars in
3 weeks, GitHub App + Action + CLI + skill.

- optional-skills/software-development/pr-lens/: SKILL.md (145 lines),
  references/ (config, graph document format, valid example) vendored
  near-verbatim, LICENSE.txt (MIT, Coldtea AI)
- gh --attach caveat handled: installed gh 2.97 lacks the flag; skill
  documents honest fallbacks (gist, canvas link, local path)
- Live smoke: validate + render of the vendored example graph passed
  (4 SVGs + manifest produced)
- docs: own catalog row + generated page + sidebar entry only
2026-09-12 20:47:00 -07:00

686 lines
17 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"schemaVersion": "0.1.1",
"kind": "graph",
"generatedAt": "2026-08-19T18:24:00.000Z",
"title": "Batch broadcast sending through Postmark",
"summary": "Broadcast delivery moves from one Postmark request per recipient to batched requests of 500, with suppression filtering pulled in front of the send and the payload builder extracted into a shared library.",
"lenses": [
"architecture",
"data-flow"
],
"provenance": {
"repo": {
"owner": "ohansemmanuel",
"name": "bestregards",
"host": "github.com"
},
"base": {
"sha": "3f5c1ab9d24e7f08c6b1a5d3e9074c2b8a6f1d40",
"ref": "main"
},
"head": {
"sha": "b71e0d4c8a92f5361de7c0b4a8f2593d6c1e8a77",
"ref": "batch-broadcast-send"
},
"pullRequest": {
"number": 128,
"title": "Send broadcasts in batches of 500",
"url": "https://github.com/ohansemmanuel/bestregards/pull/128"
},
"generator": {
"name": "pr-lens-examples",
"version": "0.1.0"
}
},
"lanes": [
{
"id": "web",
"label": "Next.js",
"subtitle": "Vercel",
"order": 0
},
{
"id": "functions",
"label": "Cloud Functions",
"subtitle": "Firebase",
"order": 1
},
{
"id": "external",
"label": "External",
"subtitle": "Postmark",
"order": 2
}
],
"nodes": [
{
"id": "broadcast-composer",
"label": "Broadcast composer",
"kind": "ui",
"delta": "unchanged",
"lane": "web",
"subtitle": "app/broadcasts/new",
"summary": "Where an author writes a broadcast and hits send. Untouched by this change.",
"files": [
{
"path": "app/broadcasts/new/page.tsx"
}
],
"badges": []
},
{
"id": "queue-route",
"label": "POST /api/broadcasts/queue",
"kind": "route",
"delta": "modified",
"lane": "web",
"summary": "Writes the queue document. Now stamps the recipient count and batch size the sender will use instead of leaving batching to the worker.",
"files": [
{
"path": "app/api/broadcasts/queue/route.ts",
"startLine": 24,
"endLine": 96
}
],
"badges": [
"+38 / -12"
]
},
{
"id": "broadcast-queue",
"label": "broadcastQueue",
"kind": "datastore",
"delta": "modified",
"lane": "functions",
"subtitle": "Firestore collection",
"summary": "Queue documents gained batchSize and suppressedCount fields, and results are now written back per batch rather than per recipient.",
"files": [
{
"path": "functions/src/broadcast/schema.ts",
"startLine": 12,
"endLine": 48
}
],
"badges": []
},
{
"id": "send-broadcast-bulk",
"label": "sendBroadcastBulk",
"kind": "function",
"delta": "added",
"lane": "functions",
"subtitle": "onWrite trigger",
"summary": "New trigger handler. Fetches suppressions once, builds batched payloads, and posts them to Postmark in chunks of 500.",
"files": [
{
"path": "functions/src/broadcast/sendBroadcastBulk.ts",
"startLine": 1,
"endLine": 142
}
],
"badges": [
"new"
]
},
{
"id": "build-bulk-payload",
"label": "buildBulkPayload",
"kind": "function",
"delta": "added",
"lane": "functions",
"summary": "Turns a broadcast and its recipient slice into a Postmark batch request body.",
"files": [
{
"path": "packages/broadcast-lib/src/buildBulkPayload.ts",
"startLine": 1,
"endLine": 74
}
],
"badges": []
},
{
"id": "get-suppressed-emails",
"label": "getSuppressedEmails",
"kind": "function",
"delta": "added",
"lane": "functions",
"summary": "Pulls the Postmark suppression dump once per broadcast so suppressed addresses are filtered before any batch is sent.",
"files": [
{
"path": "packages/broadcast-lib/src/getSuppressedEmails.ts",
"startLine": 1,
"endLine": 58
}
],
"badges": []
},
{
"id": "broadcast-lib",
"label": "broadcast-lib",
"kind": "package",
"delta": "added",
"lane": "functions",
"subtitle": "packages/broadcast-lib",
"summary": "New shared package so the queue route and the sender agree on payload shape and batch size.",
"files": [
{
"path": "packages/broadcast-lib/src/index.ts"
}
],
"badges": [
"new package"
]
},
{
"id": "process-broadcast",
"label": "processBroadcast",
"kind": "function",
"delta": "removed",
"lane": "functions",
"subtitle": "onWrite trigger",
"summary": "The per-recipient loop this change replaces.",
"files": [
{
"path": "functions/src/broadcast/processBroadcast.ts",
"startLine": 1,
"endLine": 118,
"revision": "base"
}
],
"badges": []
},
{
"id": "send-single-email",
"label": "sendSingleEmail",
"kind": "function",
"delta": "removed",
"lane": "functions",
"summary": "One Postmark request per recipient. Gone with the loop that called it.",
"files": [
{
"path": "functions/src/broadcast/sendSingleEmail.ts",
"startLine": 1,
"endLine": 46,
"revision": "base"
}
],
"badges": []
},
{
"id": "postmark",
"label": "Postmark",
"kind": "external",
"delta": "modified",
"lane": "external",
"subtitle": "Email API",
"summary": "Same provider, different endpoints: the batch endpoint and the suppression dump replace repeated single sends.",
"files": [],
"badges": []
}
],
"edges": [
{
"id": "composer-to-queue",
"from": "broadcast-composer",
"to": "queue-route",
"kind": "http",
"delta": "unchanged",
"label": "send broadcast",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "queue-to-firestore",
"from": "queue-route",
"to": "broadcast-queue",
"kind": "data",
"delta": "modified",
"label": "enqueue job",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "queue-to-lib",
"from": "queue-route",
"to": "broadcast-lib",
"kind": "dependency",
"delta": "added",
"label": "batch size",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "firestore-to-bulk",
"from": "broadcast-queue",
"to": "send-broadcast-bulk",
"kind": "event",
"delta": "added",
"label": "onWrite",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "firestore-to-process",
"from": "broadcast-queue",
"to": "process-broadcast",
"kind": "event",
"delta": "removed",
"label": "onWrite",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "process-to-single",
"from": "process-broadcast",
"to": "send-single-email",
"kind": "call",
"delta": "removed",
"label": "per recipient",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "single-to-postmark",
"from": "send-single-email",
"to": "postmark",
"kind": "http",
"delta": "removed",
"label": "POST /email · 1 msg/call",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "bulk-to-payload",
"from": "send-broadcast-bulk",
"to": "build-bulk-payload",
"kind": "call",
"delta": "added",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "bulk-to-suppressions",
"from": "send-broadcast-bulk",
"to": "get-suppressed-emails",
"kind": "call",
"delta": "added",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "bulk-to-lib",
"from": "send-broadcast-bulk",
"to": "broadcast-lib",
"kind": "dependency",
"delta": "added",
"emphasis": "normal",
"animated": false,
"files": []
},
{
"id": "suppressions-to-postmark",
"from": "get-suppressed-emails",
"to": "postmark",
"kind": "http",
"delta": "added",
"label": "GET suppression dump",
"emphasis": "normal",
"animated": true,
"files": []
},
{
"id": "bulk-to-postmark",
"from": "send-broadcast-bulk",
"to": "postmark",
"kind": "http",
"delta": "added",
"label": "500 msgs/call",
"emphasis": "hero",
"animated": true,
"summary": "The change in one edge: a broadcast to 10,000 recipients drops from 10,000 requests to 20.",
"files": []
},
{
"id": "bulk-to-firestore",
"from": "send-broadcast-bulk",
"to": "broadcast-queue",
"kind": "data",
"delta": "added",
"label": "write results",
"emphasis": "normal",
"animated": false,
"files": []
}
],
"flows": [
{
"id": "send-pipeline",
"title": "Sending a broadcast",
"summary": "The path a queued broadcast takes now, from enqueue to per-message results.",
"delta": "modified",
"participants": [
{
"node": "queue-route",
"label": "queue route"
},
{
"node": "broadcast-queue",
"label": "Firestore"
},
{
"node": "send-broadcast-bulk",
"label": "sendBroadcastBulk"
},
{
"node": "postmark",
"label": "Postmark"
}
],
"messages": [
{
"id": "enqueue",
"from": "queue-route",
"to": "broadcast-queue",
"label": "enqueue broadcast job",
"kind": "async",
"delta": "modified",
"animated": true,
"files": []
},
{
"id": "trigger",
"from": "broadcast-queue",
"to": "send-broadcast-bulk",
"label": "onWrite trigger",
"kind": "async",
"delta": "added",
"animated": true,
"files": []
},
{
"id": "suppressions-request",
"from": "send-broadcast-bulk",
"to": "postmark",
"label": "GET suppression dump",
"kind": "sync",
"delta": "added",
"animated": true,
"files": []
},
{
"id": "suppressions-response",
"from": "postmark",
"to": "send-broadcast-bulk",
"label": "suppressed addresses",
"kind": "return",
"delta": "added",
"animated": true,
"note": "Fetched once per broadcast, not once per recipient.",
"files": []
},
{
"id": "batch-post",
"from": "send-broadcast-bulk",
"to": "postmark",
"label": "POST /email/batch · 500 msgs",
"kind": "sync",
"delta": "added",
"animated": true,
"repeat": 4,
"note": "One request per 500 recipients; four for this 2,000-recipient broadcast.",
"files": []
},
{
"id": "batch-results",
"from": "postmark",
"to": "send-broadcast-bulk",
"label": "per-message results",
"kind": "return",
"delta": "added",
"animated": true,
"files": []
},
{
"id": "write-results",
"from": "send-broadcast-bulk",
"to": "broadcast-queue",
"label": "write results",
"kind": "async",
"delta": "added",
"animated": true,
"files": []
}
]
}
],
"stats": {
"filesChanged": 14,
"additions": 486,
"deletions": 212,
"chips": [
{
"label": "Postmark calls",
"value": "500× fewer",
"tone": "hero"
},
{
"label": "New",
"value": "4 units",
"tone": "added"
},
{
"label": "Retired",
"value": "2 units",
"tone": "removed"
}
]
},
"views": [
{
"id": "overview",
"title": "Architecture — blast radius",
"lens": "architecture",
"summary": "Everything this change touches, across all three lanes.",
"scope": {
"kind": "all"
},
"defaultOpen": true,
"children": [
{
"id": "new-batch-path",
"title": "The new batch path",
"lens": "architecture",
"summary": "What replaced the per-recipient loop.",
"scope": {
"kind": "selection",
"lanes": [],
"nodes": [
"send-broadcast-bulk",
"build-bulk-payload",
"get-suppressed-emails",
"broadcast-lib",
"postmark"
],
"edges": [
"bulk-to-payload",
"bulk-to-suppressions",
"bulk-to-lib",
"suppressions-to-postmark",
"bulk-to-postmark",
"bulk-to-firestore"
],
"flows": []
},
"defaultOpen": false,
"children": []
},
{
"id": "retired-path",
"title": "What was retired",
"lens": "architecture",
"summary": "The single-send path, kept visible so a reviewer can confirm nothing else called it.",
"scope": {
"kind": "selection",
"lanes": [],
"nodes": [
"process-broadcast",
"send-single-email"
],
"edges": [
"firestore-to-process",
"process-to-single",
"single-to-postmark"
],
"flows": []
},
"defaultOpen": false,
"children": []
}
]
},
{
"id": "send-pipeline-view",
"title": "Data flow — sending a broadcast",
"lens": "data-flow",
"scope": {
"kind": "selection",
"lanes": [],
"nodes": [],
"edges": [],
"flows": [
"send-pipeline"
]
},
"defaultOpen": false,
"children": []
}
],
"walkthrough": {
"steps": [
{
"id": "batches-of-500",
"heading": "sendBroadcastBulk and buildBulkPayload added",
"body": "Nothing loops over recipients any more. The sender works on a whole batch at a time.",
"stage": {
"kind": "view",
"view": "overview"
},
"focus": {
"kind": "selection",
"lanes": [],
"nodes": [
"send-broadcast-bulk",
"build-bulk-payload",
"postmark"
],
"edges": [],
"messages": []
}
},
{
"id": "suppression-first",
"heading": "getSuppressedEmails added before the send",
"body": "It pulls the blocked addresses once, before any batch is built.",
"stage": {
"kind": "view",
"view": "new-batch-path"
},
"focus": {
"kind": "selection",
"lanes": [],
"nodes": [
"get-suppressed-emails",
"postmark"
],
"edges": [],
"messages": []
}
},
{
"id": "old-path-goes-dark",
"heading": "processBroadcast and sendSingleEmail removed",
"body": "sendBroadcastBulk does their job for whole batches.",
"stage": {
"kind": "view",
"view": "overview"
},
"focus": {
"kind": "selection",
"lanes": [],
"nodes": [
"process-broadcast",
"send-single-email"
],
"edges": [],
"messages": []
}
},
{
"id": "sequence-start-to-finish",
"heading": "The send sequence gained 6 new steps",
"body": "The queue write is the only step that was there before, and it now stamps the batch size.",
"stage": {
"kind": "flow",
"flow": "send-pipeline"
},
"focus": {
"kind": "all"
}
},
{
"id": "four-batch-calls",
"heading": "Postmark now gets 500 emails per call",
"body": "One call per batch, and Postmark answers with a result for each message.",
"stage": {
"kind": "flow",
"flow": "send-pipeline"
},
"focus": {
"kind": "selection",
"lanes": [],
"nodes": [],
"edges": [],
"messages": [
"batch-post",
"batch-results"
]
}
},
{
"id": "blast-radius",
"heading": "4 parts added, 2 removed, across 3 lanes",
"body": "A 2,000-person broadcast used to make 2,000 calls to Postmark. It now makes 4.",
"stage": {
"kind": "view",
"view": "overview"
},
"focus": {
"kind": "all"
}
}
]
},
"layout": {
"direction": "right",
"laneOrder": [
"web",
"functions",
"external"
],
"rank": {
"queue-route": 0,
"send-broadcast-bulk": 1,
"postmark": 2
}
}
}