This system generates and sends weekly engineering progress reports via email. It combines project updates, AI-generated summaries, GitHub activity stats, and automated email delivery through SendGrid.
uv sync
uv pip install -r requirements.txt
uv run python tui.pyThat's it. The TUI handles everything β creating reports, editing projects, previewing, and sending.
uv run python tui.pyShows the status of projects.json (lead, team, week, project count) and three buttons:
- New Report β start a fresh report from scratch
- Edit Report β edit the current
projects.json - Preview & Send β render and send the email
Keyboard shortcuts: Q to quit, Escape to go back from any screen.
Two tabs:
Report Details β lead name, team, week dates, summary bullets, bugs/tickets metrics, next milestone.
Projects β a table of all projects with Add / Edit / Remove buttons. Each project has: name, status (π’π‘π΅π΄), status description, completed work, in-progress work, blockers, next-week plans, optional progress % and ETA.
Ctrl+S saves and writes projects.json.
Left panel: toggles for AI summary and GitHub stats, AI style selector (executive / casual / detailed), optional schedule field (YYYY-MM-DD HH:MM UTC).
Right panel: rendered email preview.
- Generate Preview β renders the email without sending
- Send Now β sends immediately (or at the scheduled time if a schedule is set)
Location: Root directory Purpose: Simple interactive wrapper that guides you through the entire process Why it exists: Bypasses complex CLI flags and provides an intuitive interface
Flow:
Check projects.json exists
β
Ask: Preview or Send?
β
Ask: Include AI? Include GitHub?
β
(If sending) Offer to archive to weekly_logs/
β
Call generate_weekly_report.generate()
β
Show success message
Purpose: Interactive wizard to build your projects.json file
Collects:
- Week start/end dates (auto-detected or manual)
- Your name and team name
- For each project:
- Project name
- Status (π’ On Track, π‘ Slight Delay, π΅ Ahead, π΄ At Risk)
- What was completed this week
- What's in progress
- Any blockers
- Plans for next week
- Overall summary bullets
- Next milestone name and date
Output: Valid JSON file that passes all Pydantic validations
Purpose: Master orchestrator that combines everything
Steps:
-
Load project data (
load_report())- Reads
projects.json - Validates with Pydantic models
- Raises errors if invalid
- Reads
-
Generate AI summary (optional)
- Uses OpenAI GPT-4o-mini
- Reads project data and creates 2-3 line friendly intro
- Styles: executive / casual / detailed
- Falls back gracefully if API fails
-
Collect GitHub stats (optional)
- Queries GitHub API for last 7 days
- Counts commits, PRs opened/merged, issues closed
- Formats as one-line summary
- Falls back gracefully if API fails
-
Render email
- Uses
PlainTextEmailRenderer - Combines all sections into plain text email
- Generates subject line with dates and project names
- Uses
-
Preview
- Shows rich console preview of final email
-
Send (if not dry-run)
- Gets recipients from
.envconfig - Sends via SendGrid API
- Confirms delivery
- Gets recipients from
CLI Flags (if calling directly):
python -m scripts.generate_weekly_report \
--input projects.json \
--dry-run \
--skip-ai \
--skip-github \
--style executive \
--github-days 7 \
--to "email1@example.com,email2@example.com"Purpose: Converts structured report data into formatted email text
Class: PlainTextEmailRenderer
Template Structure:
[π€ AI Intro if enabled]
---
Hi team,
Here's a summary of this week's progress across active projects:
### 1. Project Name
Status: π’ On Track
Progress:
- Completed: [what was done]
- In Progress: [what's being worked on]
- Blockers: [any issues]
Next Week:
- [plans]
### 2. [More projects...]
Overall Summary:
- [auto-generated bullet: X/Y projects on track]
- [custom bullets]
- π» [GitHub stats if enabled]
Next Milestone:
- [milestone name] β [date]
Best,
[Your Name]
Software Engineer
([Team Name])
Note: Currently generates plain text with markdown-style formatting (###, -, etc.). This doesn't render well in most email clients.
Purpose: Generates friendly 2-3 line AI intros using OpenAI
How it works:
- Builds context from project data (status, completed work, blockers)
- Sends to OpenAI with style-specific instructions
- Returns summary like:
- "Hi there! This is Claude, Sebastian's AI assistant. This week showed solid progress with 3/4 projects on track. The API Platform hit all milestones while the Web App has a minor delay waiting on design assets."
API: Uses OpenAI GPT-4o-mini (cheapest model) Token limit: 150 tokens max Temperature: 0.7 (balanced creativity)
Configured in .env:
OPENAI_API_KEYAI_SYSTEM_PROMPT(optional override)AI_MAX_TOKENS(optional)AI_TEMPERATURE(optional)
Purpose: Collects GitHub activity stats for the past 7 days
What it tracks:
- Commits pushed
- Pull requests opened
- Pull requests merged
- Issues closed
- Across all configured repositories
Output: One-line summary like:
"This week: 23 commits, 5 PRs opened (4 merged), 3 issues closed"
Configured in .env:
GITHUB_TOKEN=ghp_xxxxxxxxxxxxx
GITHUB_REPOS=owner/repo1,owner/repo2,owner/repo3Purpose: Sends emails via SendGrid API
Flow:
- Formats plain text email
- Calls SendGrid API with:
- From address (configured in
.env) - To addresses (from config or CLI override)
- Subject line
- Body text
- From address (configured in
- Handles errors and retries
Configured in .env:
SENDGRID_API_KEY=SG.xxxxxxxxxxxxx
SENDGRID_FROM_EMAIL=reports@yourcompany.com
REPORT_RECIPIENT_EMAILS=manager@company.com,team@company.comPurpose: Pydantic models for type safety and validation
Models:
ON_TRACKβ π’ On TrackSLIGHT_DELAYβ π‘ Slight DelayAHEADβ π΅ Ahead of ScheduleAT_RISKβ π΄ At Risk
name: Project name (required)status: ProjectStatus (default: ON_TRACK)status_text: Custom status descriptioncompleted: What was done this weekin_progress: Current workblockers: Issues blocking progressnext_week: Plans for next week
week_start: Start dateweek_end: End date (validated to be after start)lead_name: Your name (required)team_name: Team name (default: "Product Engineering")projects: List of ProjectUpdate (min 1 required)summary_bullets: Overall summary pointsnext_milestone: Next major milestonenext_milestone_date: Target date (optional)
Validation:
- Ensures dates are valid
- Ensures at least one project exists
- Trims whitespace from names
- Validates project names aren't empty
Create a .env file in the root directory with:
# GitHub Integration
GITHUB_TOKEN=ghp_your_github_token_here
GITHUB_REPOS=username/repo1,username/repo2
# SendGrid Email
SENDGRID_API_KEY=SG.your_sendgrid_api_key
SENDGRID_FROM_EMAIL=your-email@company.com
REPORT_RECIPIENT_EMAILS=recipient1@company.com,recipient2@company.com
# OpenAI for AI Summaries
OPENAI_API_KEY=sk-your-openai-api-key
OPENAI_MODEL=gpt-4o-mini
# Optional AI Settings
AI_SYSTEM_PROMPT="You are a helpful engineering assistant..."
AI_MAX_TOKENS=150
AI_TEMPERATURE=0.7
# Report Settings
REPORT_OUTPUT_DIR=./reports
LOG_LEVEL=INFOnyon/
βββ tui.py # TUI entry point (start here)
βββ weekly_report.py # Legacy CLI entry point
βββ projects.json # Current week's report data (generated)
βββ weekly_logs/ # Archived reports (auto-created)
β βββ report_2025-10-07.json
β βββ report_2025-10-14.json
βββ scripts/
β βββ create_projects_json.py # Interactive data collection
β βββ generate_weekly_report.py # Core report generator
βββ core/
β βββ email_renderer.py # Email template rendering
β βββ email_sender.py # SendGrid integration
β βββ github_collector.py # GitHub API client
βββ ai/
β βββ summarizer.py # OpenAI integration
βββ data/
β βββ models.py # Pydantic data models
β βββ github_models.py # GitHub-specific models
βββ config/
β βββ settings.py # Configuration management
βββ utils/
β βββ json_exporter.py # JSON file writer
β βββ github_stats_formatter.py # Format GitHub stats
β βββ logger.py # Logging setup
βββ .env # Configuration (not in git)
-
Current report:
projects.json(root directory)- Overwrites each time you create a new one
-
Archived reports:
weekly_logs/report_YYYY-MM-DD.json- Only saved when you choose "send" mode
- Only saved if you confirm the archive prompt
- Named by week start date
- Permanent historical record
- If you only use "preview" mode, nothing gets archived
- The
weekly_logs/directory will remain empty - Only reports that are actually sent get logged
- This is intentional to avoid cluttering logs with drafts
# Clone and install
uv sync
uv pip install -r requirements.txt
# Configure .env
cp .env.example .env
# Fill in GITHUB_TOKEN, SENDGRID_API_KEY, OPENAI_API_KEY, etc.
# Launch the TUI
uv run python tui.py
# Hit "New Report" to create your first report, then "Preview & Send" to testuv run python tui.py
# β New Report (or Edit Report if updating last week's)
# β Fill in project details, save
# β Preview & Send β Generate Preview
# β Send Now when readyuv run python tui.py
# β Preview & Send
# β Toggle off AI Summary and GitHub Stats
# β Generate Preview, then Send Now# Full control over all options
uv run python -m scripts.generate_weekly_report \
--input projects.json \
--style casual \
--github-days 14 \
--to "override@example.com"Cause: No --input flag provided when calling generate_weekly_report.py directly
Fix: Use python weekly_report.py instead, or add --input projects.json
Cause: Dependencies not installed
Fix: source venv/bin/activate && pip install -r requirements.txt
Cause: Invalid data in projects.json
Fix: Delete projects.json and recreate with python scripts/create_projects_json.py
Cause: Invalid SendGrid API key or rate limit
Fix: Check .env file, verify key is valid in SendGrid dashboard
Cause: Invalid OpenAI key or quota exceeded
Fix: Use --skip-ai flag or check OpenAI account
Cause: Only previewing reports, never sending them Fix: Choose "send" mode and confirm archiving to save logs
Subject:
Weekly Engineering Progress β 2025-10-07β2025-10-11 (API Platform, Web App)
Body: Plain text with markdown-style formatting
- Uses
###for headers - Uses
-for bullets - Uses emojis (π’, π‘, π΄, π΅, π€, π»)
- No HTML styling
Issue: Markdown doesn't render in most email clients (Gmail, Outlook, etc.)
Result: Recipients see raw markdown syntax like ### and -
Needed: HTML email renderer with proper styling
-
HTML Email Renderer
- Replace plain text with HTML email template
- Add proper styling (headers, colors, spacing)
- Make it look professional in Gmail/Outlook
- Keep plain text as fallback
-
Automatic Archiving
- Save to
weekly_logs/even in preview mode - Add timestamped backups before overwriting
projects.json
- Save to
-
Email Template Improvements
- Better visual hierarchy
- Status badges with colors
- Responsive design for mobile
- Company branding
OpenAI (AI Summaries):
- Model: GPT-4o-mini
- Cost: ~$0.0001 per report
- Max tokens: 150
GitHub API:
- Free (5,000 requests/hour with token)
SendGrid:
- Free tier: 100 emails/day
- Each report = 1 email per recipient
Estimated cost for weekly reports: < $0.01/week
- Never commit
.envfile - Contains API keys .gitignoreincludes.env,projects.json,weekly_logs/- GitHub token needs:
reposcope (read access) - SendGrid key needs:
Mail Sendpermission only - OpenAI key: Standard API access
The system provides a complete end-to-end workflow for weekly engineering reports:
- Data Collection β Interactive wizard (
create_projects_json.py) - AI Enhancement β OpenAI summary (
ai/summarizer.py) - GitHub Stats β Activity tracking (
core/github_collector.py) - Email Rendering β Text formatting (
core/email_renderer.py) - Delivery β SendGrid sending (
core/email_sender.py) - Archiving β Historical logs (
weekly_logs/)
Main Entry Point: python weekly_report.py
Just run it and follow the prompts!