Generates a local HTML digest of GitHub PRs (review requests + your open PRs) and Jira issues from two JQL queries. You can refresh it on a schedule (for example every 30 minutes via cron) or run the script by hand; output is a single bookmarkable HTML file.
-
Install GitHub CLI (
gh) and authenticate (gh auth login). For cron, usegh auth loginonce or setGH_TOKENin your config. -
Create an Atlassian API token. The script calls Jira’s REST API v3 enhanced search (
POST /rest/api/3/search/jql); the old/rest/api/2/searchendpoint returns HTTP 410 on current Jira Cloud. -
Copy the example config and edit it:
cp .morning-digest-config.example ~/.morning-digest-config chmod 600 ~/.morning-digest-config
Or keep the file next to the script as
.morning-digest-config. You can also setMORNING_DIGEST_CONFIGto any path. -
Run:
chmod +x generate-digest.sh ./generate-digest.sh
-
Open the printed
file://path, or use the default output underOUTPUT_DIR/OUTPUT_FILENAME(see the example file).
All behavior is driven by the config file. Required variables:
| Variable | Purpose |
|---|---|
GITHUB_USERNAME |
GitHub user for gh search prs |
JIRA_EMAIL |
Jira login email (REST auth) |
JIRA_URL |
Jira Cloud base URL, e.g. https://your-org.atlassian.net |
JIRA_API_TOKEN |
Atlassian API token |
BLOCKER_JQL |
JQL for the first Jira section |
YOUR_TICKETS_JQL |
JQL for your tickets section |
Optional variables (defaults in the script): OUTPUT_DIR, OUTPUT_FILENAME, GH_PR_LIMIT, JIRA_MAX_RESULTS, DIGEST_PAGE_TITLE, section headings/descriptions, GH_TOKEN.
See .morning-digest-config.example for the full list and comments.
The digest HTML is still written. A yellow banner lists every failed source with a short message (stderr from gh, HTTP status and Jira error text from curl, etc.). Each affected section has a red box with the same detail. Summary numbers show — for failed sources. Messages are truncated and HTML-escaped. If you use cron, the script also prints a one-line WARNING to stderr so logs flag partial failures.
You do not need to wait for cron. Regenerate the HTML whenever you want (same config and output paths as cron):
/bin/bash "$HOME/local-cron-jobs/morning-digest/generate-digest.sh"If your clone lives somewhere else, point at that directory:
cd /path/to/morning-digest && ./generate-digest.shThe script prints the output path and a file:// URL when it finishes. Ensure gh, curl, and jq are on your PATH (interactive shells usually already have them).
Browser refresh only reloads the saved HTML from disk; it does not run generate-digest.sh or call GitHub/Jira. After you run the script (or cron runs), refresh the tab to see the updated file.
With the example crontab below, the digest runs only during the day, in the machine’s local timezone (what the date command shows):
- Every day (including weekends): at :00 and :30 past each hour from 8:00 AM through 5:30 PM, and once more at 6:00 PM.
- Does not run before 8:00 AM, after 6:00 PM, or overnight.
So the first run is 8:00, then 8:30, 9:00, … 17:30, 18:00; there is no 6:30 PM run.
Set DIGEST_ROOT (and the local-cron-jobs/morning-digest path) to match where you cloned this repo. User crontabs normally define HOME.
Three lines: half-hours for hours 8–17, a single 18:00 run, and an end-of-month token snapshot.
0,30 8-17 * * * DIGEST_ROOT=$HOME/local-cron-jobs/morning-digest; mkdir -p $HOME/.local/share/morning-digest && PATH=$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin /bin/bash $DIGEST_ROOT/generate-digest.sh >> $HOME/.local/share/morning-digest/cron.log 2>&1
0 18 * * * DIGEST_ROOT=$HOME/local-cron-jobs/morning-digest; mkdir -p $HOME/.local/share/morning-digest && PATH=$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin /bin/bash $DIGEST_ROOT/generate-digest.sh >> $HOME/.local/share/morning-digest/cron.log 2>&1
55 23 28-31 * * PATH=$HOME/.local/bin:/usr/local/bin:/usr/bin:/bin /bin/bash $HOME/local-cron-jobs/morning-digest/capture-monthly-snapshot.sh >> $HOME/.local/share/morning-digest/cron.log 2>&1The script loads ~/.morning-digest-config or .morning-digest-config next to generate-digest.sh on its own; you do not need to source the config in the crontab line unless you prefer to.
Ensure PATH includes gh (often under ~/.local/bin after gh install), plus curl and jq.
capture-monthly-snapshot.sh runs at 23:55 on days 28–31 and exits immediately unless today is actually the last day of the month. On the real last day it calls rtk gain --format json --monthly, extracts the current month's stats, and appends them to:
~/.local/share/morning-digest/monthly-snapshots.json
Each entry records input_tokens, output_tokens, saved_tokens, savings_pct, and captured_at (ISO timestamp). The digest reads this file and shows a Historical snapshots section in the RTK panel — one card per completed month, showing the final spend and savings for that month. This preserves the record even if you later reset RTK stats with rtk gain --reset.
To backfill a previous month manually, run the script on the last day of that month (or just edit the JSON file directly — it's a plain array sorted by month).