Awesome-omni-skill newsletter-events-write
Generate markdown newsletters from stored events. Use when the user wants to create, write, or generate a newsletter from scraped events.
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/newsletter-events-write-aniketpanjwani" ~/.claude/skills/diegosouzapw-awesome-omni-skill-newsletter-events-write-73d076 && rm -rf "$T"
skills/development/newsletter-events-write-aniketpanjwani/SKILL.md<essential_principles>
How This Skill Works
This skill generates markdown newsletters from events stored in SQLite. The workflow splits responsibility:
- CLI tool handles fragile data operations (paths, types, queries)
- Claude handles creative generation (interpreting preferences, formatting)
Key Concept: Natural Language Formatting
Users describe how they want newsletters formatted in plain English. You interpret these instructions directly - no templates or structured syntax needed.
Example preference from config:
formatting_preferences: | Organize by date with each day as a section header. Use emojis: 🎵 music, 🎨 art, 🍴 food. Format: **Title** @ Venue | Time | Price
Data Source
Events are stored in SQLite at
~/.config/local-media-tools/data/events.db.
Config is at ~/.config/local-media-tools/sources.yaml.
Output
Generated markdown saved to
./newsletter_YYYY-MM-DD.md in the current working directory.
</essential_principles>
<critical>
## Use CLI for Data Loading - Never Inline Python
NEVER write inline Python to load events or config. Use the CLI tool:
# Get plugin directory first PLUGIN_DIR=$(cat ~/.claude/plugins/installed_plugins.json | jq -r '.plugins["newsletter-events@local-media-tools"][0].installPath') # Load events and preferences (default: next 7 days) cd "$PLUGIN_DIR" && uv run python scripts/cli_newsletter.py load --days 7
The CLI tool handles:
- Correct database path resolution
- Proper date type conversions
- Loading formatting preferences from config
- Returning structured JSON
Do NOT:
- Write inline Python to query the database
- Hardcode paths to config or database
- Import schema modules directly </critical>
cat ~/.claude/plugins/installed_plugins.json | jq -r '.plugins["newsletter-events@local-media-tools"][0].installPath'
Save the output path as
PLUGIN_DIR.
Step 1: Load Data with CLI
Run the CLI to get events and formatting preferences:
cd "$PLUGIN_DIR" && uv run python scripts/cli_newsletter.py load --days 7
Or for a specific date range:
cd "$PLUGIN_DIR" && uv run python scripts/cli_newsletter.py load --from 2025-01-01 --to 2025-01-14
Output: JSON containing:
- Newsletter titlenewsletter_name
- Geographic regionregion
- User's natural language formatting instructionsformatting_preferences
- Start and end datesdate_range
- Number of eventsevent_count
- Array of event objectsevents
If no events found, the CLI returns an error with suggestions.
Step 2: Generate Newsletter (Your Creative Task)
Using the JSON output from Step 1, generate markdown that follows the
formatting_preferences.
Your task: Interpret the natural language preferences and apply them creatively:
- Read the
fieldformatting_preferences - Adapt raw event descriptions to match user's desired style
- Apply emoji rules, formatting patterns, organization
- Generate readable, well-structured markdown
Available Fields Reference
Each event in the
events array has:
| Field | Description | Example |
|---|---|---|
| Event name | "Jazz Night" |
| Venue name | "The Blue Note" |
| Venue city | "Kingston" |
| ISO date | "2025-01-20" |
| Full day name | "Saturday" |
| Human-readable date | "January 20" |
| Start time | "8:00 PM" or null |
| Event description | "Live jazz trio..." |
| Event category | "music", "art", "food_drink" |
| Price or null | "$15" |
| Boolean | true/false |
| Link to buy tickets | URL or null |
| Link to event page | URL or null |
| Where event was found | URL or null |
Formatting Guidelines
- Read preferences carefully - follow user instructions exactly
- Handle nulls gracefully - skip fields that are null/missing
- Sort appropriately - events come pre-sorted by date then time
- Be creative - adapt descriptions to match user's style
Step 3: Save Output
Write the generated markdown to the current working directory:
./newsletter_YYYY-MM-DD.md
Use today's date for the filename.
Step 4: Display Preview
Show the first ~50 lines of generated markdown so user can review.
Report:
- Output file path
- Number of events included
- Date range covered </workflow>
<error_handling>
No Events Found
The CLI will return:
{ "error": "no_events", "message": "No events found from 2025-01-01 to 2025-01-07", "suggestion": "Run /newsletter-events:research to scrape new events, or try a wider date range with --days 14" }
Report this to the user with the suggestion.
No Formatting Preferences
If
formatting_preferences is null or empty, use sensible defaults:
Organize events chronologically by date. Use section headers for each day (e.g., "## Saturday, January 20"). Include event title, venue, time, and price. Keep formatting simple and readable.
Database Not Found
The CLI will return:
{ "error": "database_not_found", "message": "Database not found at ~/.config/local-media-tools/data/events.db", "suggestion": "Run /newsletter-events:research to scrape events first" }
</error_handling>
<success_criteria> Newsletter generation is complete when:
- CLI tool used to load events (not inline Python)
- Formatting preferences interpreted correctly
- Markdown generated following user's preferences
- Output saved to
./newsletter_YYYY-MM-DD.md - Preview displayed to user </success_criteria>