← Commit history
README.md+13−4
@@ -9,10 +9,18 @@ wiki notification email ──poll──> per-item state ──render──> ONE         └──sweep──> trash / archive / label ``` -The board is a single card, one row per issue: **status** (OPEN green /-CLOSED gray), **page + issue #**, **origination date**, **actor**, **title**,-**last activity**, and a **View link at the end of the row**. New activity-bubbles to the top. Open items stay on the board until resolved; when an item+The board is a single card holding a **table** - a header row and one row per+issue with consistent columns:++```+STATUS | ITEM | TITLE | BY | OPENED | LAST | LINK+```++**status** (OPEN green / CLOSED gray), **page + issue #**, title, **actor**,+**origination date**, last activity, and a **View link at the end of the+row**. New activity bubbles to the top. (Chat cards have no native table+widget, so the table is rendered as consistent pipe-separated columns; set+`"style": "blocks"` for a chunkier per-item layout instead.) Open items stay on the board until resolved; when an item is closed it shows CLOSED - so you get the satisfaction of seeing it done - then drops off at **6am the next day** to keep the board fresh. @@ -99,6 +107,7 @@ inbox. A failed board post never sweeps the email; it retries next pass. | `timezone` | container local | IANA zone for dates + the purge | | `maxRows` | `40` | card row cap | | `boardTitle` | `Wiki Notifications` | card header |+| `style` | `table` | `table` (pipe-column table) or `blocks` (per-item blocks with View buttons) |  ## Commands 
SKILL.md+2
@@ -41,6 +41,8 @@ wiki-notify-gchat install-cron    # keep the board live every 2 min - `timezone`: IANA zone (e.g. `America/New_York`) so the 6am closed-item   purge lands in the user's morning; container default is often UTC. - `purgeHour`, `maxRows`, `pollSeconds`, `boardTitle` as needed.+- `style`: `table` (default - pipe-column table with header row) or `blocks`+  (per-item blocks with View buttons). Chat cards have no native table widget.  ## How the board updates (why you may see a delete) 
bin/__pycache__/wiki-notify-gchatcpython-312.pyc
⋯ 1 unchanged line ⋯
bin/wiki-notify-gchat+40−9
@@ -44,6 +44,7 @@ DEFAULT_CONFIG = {     "timezone": "",     "maxRows": 40,     "boardTitle": "Wiki Notifications",+    "style": "table", }  OPEN_COLOR, CLOSED_COLOR = "#22c55e", "#94a3b8"@@ -279,6 +280,44 @@ def render_card(items, cfg):     n_closed = len(rows) - n_open     max_rows = int(cfg.get("maxRows", 40))     shown, overflow = rows[:max_rows], max(0, len(rows) - max_rows)+    if cfg.get("style", "table") == "table":+        widgets = render_table_widgets(shown, tz)+    else:+        widgets = render_block_widgets(shown, tz)+    if overflow:+        widgets.append({"textParagraph": {"text": f"<i>+{overflow} older item(s) not shown</i>"}})+    if not shown:+        widgets = [{"textParagraph": {"text": "No wiki notifications. Inbox clean."}}]+    subtitle = f"{n_open} open · {n_closed} closed · updated {datetime.now(tz).strftime('%b %-d %H:%M')}"+    return {"cardsV2": [{"cardId": "wiki-notify-board", "card": {+        "header": {"title": cfg.get("boardTitle", "Wiki Notifications"), "subtitle": subtitle},+        "sections": [{"widgets": widgets}],+    }}]}+++def render_table_widgets(shown, tz):+    """One text block: a pipe-separated table, header row + one line per item.+    Chat cards have no native table widget (columns caps at 2), so consistent+    pipe columns are the closest faithful table rendering."""+    import html as html_mod+    cells = ["STATUS", "ITEM", "TITLE", "BY", "OPENED", "LAST", "LINK"]+    lines = ["<b>" + " | ".join(cells) + "</b>"]+    for it in shown:+        is_open = it["status"] == "open"+        status = (f'<font color="{OPEN_COLOR}"><b>OPEN</b></font>' if is_open+                  else f'<font color="{CLOSED_COLOR}"><b>CLOSED</b></font>')+        item = it["page"] + (f" #{it['num']}" if it["num"] else "")+        title = it["title"][:48] + ("…" if len(it["title"]) > 48 else "")+        title = html_mod.escape(title, quote=False)+        by = it["actor"] or "-"+        opened = fmt_date(it["openedAt"], tz)+        last = f"{EVENT_LABEL.get(it['lastEvent'], it['lastEvent'])} {fmt_datetime(it['lastAt'], tz)}"+        link = f'<a href="{it["url"]}">View</a>' if it["url"] else "-"+        lines.append(" | ".join([status, item, title, by, opened, last, link]))+    return [{"textParagraph": {"text": "<br>".join(lines)}}]+++def render_block_widgets(shown, tz):     widgets = []     for it in shown:         is_open = it["status"] == "open"@@ -298,15 +337,7 @@ def render_card(items, cfg):             w["decoratedText"]["button"] = {                 "text": "View", "onClick": {"openLink": {"url": it["url"]}}}         widgets.append(w)-    if overflow:-        widgets.append({"textParagraph": {"text": f"<i>+{overflow} older item(s) not shown</i>"}})-    if not widgets:-        widgets = [{"textParagraph": {"text": "No wiki notifications. Inbox clean."}}]-    subtitle = f"{n_open} open · {n_closed} closed · updated {datetime.now(tz).strftime('%b %-d %H:%M')}"-    return {"cardsV2": [{"cardId": "wiki-notify-board", "card": {-        "header": {"title": cfg.get("boardTitle", "Wiki Notifications"), "subtitle": subtitle},-        "sections": [{"widgets": widgets}],-    }}]}+    return widgets   def items_hash(items):
docs/board.png
⋯ 1 unchanged line ⋯
docs/hero.png
⋯ 1 unchanged line ⋯
package.json+2−2
@@ -2,7 +2,7 @@   "slug": "wiki-notify-gchat",   "title": "Wiki Notify for Google Chat",   "type": "app",-  "version": "1.0.2",+  "version": "1.1.0",   "description": "Turn wiki.adom.inc notification emails into a live Google Chat board. One card, one row per issue - newest first, OPEN/CLOSED status, origination date, actor, and a View link - continuously updated in your own Chat space via your own webhook. Emails are swept out of your inbox (trash, archive, or label). Closed items linger until 6am the next day, then drop off. Delegates all auth to adom-google; the only secret is your webhook URL, kept in your private config.",   "tags": [     "cli",@@ -39,7 +39,7 @@   },   "hero": {     "headline": "Wiki Notify for Google Chat",-    "subhead": "Wiki notifications become a live Chat board - your inbox stays clean.",+    "subhead": "Wiki notifications become a live table in Chat - your inbox stays clean.",     "screenshot": "docs/hero.png"   } }
page.json+1−1
@@ -2,7 +2,7 @@   "slug": "wiki-notify-gchat",   "title": "Wiki Notify for Google Chat",   "type": "app",-  "version": "1.0.2",+  "version": "1.1.0",   "description": "Turn wiki.adom.inc notification emails into a live Google Chat board. One card, one row per issue - newest first, OPEN/CLOSED status, origination date, actor, and a View link - continuously updated in your own Chat space via your own webhook. Emails are swept out of your inbox (trash, archive, or label). Closed items linger until 6am the next day, then drop off. Delegates all auth to adom-google; the only secret is your webhook URL, kept in your private config.",   "tags": [     "cli",