Skip to content
Back to skills

Weekly Aeoncard

ASecurity

Build a weekly token-consumption recap image from memory/token-usage.csv - this week + all-time totals, top skills, rendered as a shareable SVG card.

  • 766 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 3, 2026
ai-agentspythongobashnodegitapi

Works with

  • api

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 2, 2026

npx -y skills add aeonfun/aeon --skill weekly-aeoncard --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Weekly Aeoncard?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Weekly Aeoncard
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aeonfun-weekly-aeoncard/badge)](https://www.skillsdirectory.com/skills/aeonfun-weekly-aeoncard)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: weekly-aeoncard
description: Build a weekly token-consumption recap image from memory/token-usage.csv - this week + all-time totals, top skills, rendered as a shareable SVG card.
metadata:
  title: Weekly Aeon Card
  mode: write
  category: productivity
  var: ""
  tags:
    - monitoring
    - meta
  capabilities:
    - sends_notifications
---
> **${var}** — window + delivery control.
> - **empty** → weekly card: last 7 days + all-time, render the image, notify.
> - **`dry-run`** → render the image + report + dashboard spec but send no notification (artifacts still write). Combine with a window, e.g. `dry-run 30`.
> - **integer `N`** → override the weekly window to the last `N` days (default 7, cap 90). Example: `14`, `30`.

Today is ${today}. Turn this instance's own token ledger (`memory/token-usage.csv`) into a one-glance recap: how many tokens it burned **this week**, how many **since it started**, which skills dominate — rendered as a self-contained SVG card an operator can screenshot and share. Every number is measured from the ledger; nothing is fetched, sampled, or estimated. The heavy lifting is in `skills/weekly-aeoncard/render_card.py` (pure Python stdlib, deterministic) so you orchestrate, not hand-compute.

## Steps

1. **Parse `${var}` → window + mode.**
   ```bash
   V="$(echo "${var}" | tr '[:upper:]' '[:lower:]' | xargs)"
   MODE=execute; case "$V" in dry-run*) MODE=dry-run; V="${V#dry-run}"; V="$(echo "$V" | xargs)";; esac
   WINDOW_DAYS=7; case "$V" in ''|*[!0-9]*) : ;; *) WINDOW_DAYS="$V";; esac
   [ "$WINDOW_DAYS" -gt 90 ] 2>/dev/null && WINDOW_DAYS=90
   [ "$WINDOW_DAYS" -lt 1 ] 2>/dev/null && WINDOW_DAYS=7
   ```

2. **Guard the ledger.** The recap is synthesis-only — no ledger, nothing to show.
   ```bash
   CSV=memory/token-usage.csv
   if [ ! -s "$CSV" ] || [ "$(wc -l < "$CSV")" -lt 2 ]; then
     ./notify "weekly-aeoncard skipped: memory/token-usage.csv absent or empty (no runs recorded yet)"
     exit 0   # WEEKLY_AEONCARD_NO_DATA
   fi
   ```

3. **Derive the instance name + image link.** From the git origin, so the card self-labels and the notification deep-links the committed SVG.
   ```bash
   REMOTE="$(git remote get-url origin 2>/dev/null)"
   REPO="$(echo "$REMOTE" | sed -E 's#.*github.com[:/]([^/]+/[^/.]+)(\.git)?/?$#\1#')"
   INSTANCE="${REPO#*/}"; [ -n "$INSTANCE" ] || INSTANCE=aeon
   SVG="output/images/weekly-aeoncard-${today}.svg"
   IMG_LINK="https://github.com/${REPO}/blob/main/${SVG}"
   ```

4. **Render the card + artifacts.** One call writes the SVG (canonical image), a best-effort PNG, the markdown report, the dashboard spec, and appends the run log. It prints a one-line JSON summary on stdout — capture it.
   ```bash
   mkdir -p output/images output/articles apps/dashboard/outputs
   # The PNG (a raster copy committed next to the SVG) needs a rasterizer. The workflow stages `rsvg-convert`
   # (librsvg2-bin) for this skill before the run — the agent allowlist blocks in-run
   # pip/apt. render_card.py uses cairosvg if importable, else rsvg-convert, else SVG-only.
   SUMMARY="$(python3 skills/weekly-aeoncard/render_card.py \
     --csv "$CSV" --today "${today}" --window-days "$WINDOW_DAYS" \
     --instance "$INSTANCE" --img-link "$IMG_LINK" \
     --out "$SVG" \
     --png "output/images/weekly-aeoncard-${today}.png" \
     --report "output/articles/weekly-aeoncard-${today}.md" \
     --dashboard "apps/dashboard/outputs/weekly-aeoncard.json" \
     --log "memory/logs/${today}.md")"
   RC=$?
   if [ "$RC" -ne 0 ]; then
     ./notify "weekly-aeoncard: render failed (rc=$RC) — ledger unreadable"
     exit 0
   fi
   ```
   All writes land under `output/` and `apps/dashboard/outputs/` - paths the run commits. The PNG is a raster copy committed next to the SVG (needs `cairosvg` or `rsvg-convert`); if neither is available the SVG stands alone as the canonical image. Either way the notify is a text recap + link.

5. **Read the numbers back.** Parse `$SUMMARY` for the notification (it holds `week_human`, `week_runs`, `life_human`, `life_runs`, `since`, `cache_read_pct`, `top_week`):
   ```bash
   WK=$(echo "$SUMMARY" | jq -r .week_human); WKR=$(echo "$SUMMARY" | jq -r .week_runs)
   LF=$(echo "$SUMMARY" | jq -r .life_human); LFR=$(echo "$SUMMARY" | jq -r .life_runs)
   SINCE=$(echo "$SUMMARY" | jq -r .since)
   TOP=$(echo "$SUMMARY" | jq -r '[.top_week[:3][] | "\(.[0]) \(.[1]/1e6|floor)M"] | join(", ")')
   PNG=$(echo "$SUMMARY" | jq -r '.png // ""')   # empty when no rasterizer was available
   ```

6. **Log.** The render step already appended a `### weekly-aeoncard` block to `memory/logs/${today}.md` (window, weekly + all-time totals, top skills, image path, `WEEKLY_AEONCARD_OK`). Do not duplicate it.

7. **Notify.** If `MODE` is `dry-run`, skip this step (log `WEEKLY_AEONCARD_DRY_RUN` and stop - the image, report, and dashboard spec are already written). Otherwise send the recap + the committed card link via `./notify -f`. `./notify` is text-only: it has no `--photo`/`--video` flag (an unknown flag exits 2 and sends nothing), so never attach the image:
   ```bash
   [ "$MODE" = dry-run ] && exit 0
   BODY="This week (${WINDOW_DAYS}d): ${WK} tokens · ${WKR} runs
   All-time: ${LF} tokens · ${LFR} runs (since ${SINCE})
   Top this week: ${TOP}
   Card: ${IMG_LINK}"
   # Body from a file (any length); the card itself ships as the IMG_LINK in the body.
   NOTE_FILE="${TMPDIR:-/tmp}/weekly-aeoncard-notify.md"
   echo "$BODY" > "$NOTE_FILE"
   ./notify --title "Weekly Aeon Card - ${INSTANCE}" -f "$NOTE_FILE"
   ```

## Network note

The skill issues no `gh api` and puts no secrets on the command line. Stats are read from `memory/token-usage.csv`; the card is rendered by `skills/weekly-aeoncard/render_card.py` using only the Python standard library (deterministic - `${today}` is passed in, never read from the clock). To also emit a raster PNG it uses `cairosvg` (best-effort `pip install`) or an `rsvg-convert` fallback - both optional; without them the run still succeeds with the SVG as the image. The image link is built from `git remote get-url origin` (a local read). Delivery goes through `./notify`, a text-only queue-writer (the post-run notify step owns the channel tokens and does the send).

## Constraints

- **Synthesis-only.** Every number is measured from the ledger. If the ledger is missing a skill's runs, that skill simply doesn't appear — never invent rows.
- **Write skill.** It renders and commits artifacts, so it is `mode: write` (the read-only tier withholds `Bash(python3:*)` — an interpreter is a write vector — so a Python-rendered card cannot run read-only; a Node renderer could, but this skill is honestly a write). All file writes still happen inside `render_card.py` (Python `open()`) for deterministic, single-shot output.
- **Idempotent.** Same-day reruns overwrite `output/images/weekly-aeoncard-${today}.svg`, the report, and the dashboard spec; the log block appends (one per run) so reruns show drift.
- **The SVG is the deliverable.** The PNG is a convenience for chat/social; its absence is never an error.

Files in this skill

  • SKILL.md7.1 KB
  • render_card.py11.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.