Daily AI news tracking skill that runs inside AI coding tools (Claude Code, Codex, OpenCode, Hermes, Cursor, ClawHub). Not a standalone service — no Docker, no servers. Invoked via /morning-ai or by reading SKILL.md.
- Language: Python 3.9+
- Dependencies: stdlib only — no
requirements.txt, nopyproject.toml. Usesurllib,json,xml.etree,smtplib,email.mime,string.Template,dataclasses. - Distribution: source files only. Plugin manifests for Claude Code (
.claude-plugin/) and Codex (.codex-plugin/). - Schedule frequency: daily at 08:00 UTC+8 (idempotent, unattended).
SKILL.md # Main entry point (symlinked from skills/morning-ai/)
AGENTS.md # Auto-discovery for OpenCode/Hermes/Codex
.claude-plugin/ # Claude Code plugin metadata + marketplace
.codex-plugin/ # OpenAI Codex plugin metadata
lib/ # Shared Python modules (collectors, scoring, dedupe, IO)
skills/
├── morning-ai/ # Main orchestrator (SKILL.md is a symlink to root)
├── tracking-list/ # Step 1: Python collectors → data_{date}.json
├── leaderboard/ # Optional: leaderboard ranking diff over time
├── gen-infographic/ # Step 4: image generation (5 styles)
├── gen-social/ # Step 5: per-platform social copy (X, Xiaohongshu)
├── gen-message/ # Step 6: message digest for chat platforms
└── gen-email/ # Step 7: SMTP email subscription
entities/ # 80+ tracked entities organized by group (markdown tables)
templates/ # Report templates
docs/ # Style previews, email setup guide, etc.
tests/ # Unit tests (stdlib unittest)
All sub-skills consume the same data_{YYYY-MM-DD}.json produced by Step 1, so each output channel sees identical scored / deduped / verified items.
collect.py (Step 1) → data_{date}.json
→ tracking-list/SKILL.md (Step 2: spec for AI agent)
→ report_{date}.md (Step 3: structured report)
→ gen-infographic/ (Step 4, optional: cover + per-type images)
→ gen-social/ (Step 5, optional: per-platform copy)
→ gen-message/ (Step 6, optional: chat digest)
→ gen-email/ (Step 7, optional: SMTP delivery)
Loaded by lib/env.py in this priority order (later overrides earlier):
~/.config/morning-ai/.env(global).claude/morning-ai.env(project).env(project, gitignored).env.local(local-only)- Environment variables matching prefixes:
MORNING_AI_,GITHUB_,IMAGE_GEN_,IMAGE_STYLE,GEMINI_,MINIMAX_,SOCIAL_,MESSAGE_,EMAIL_
When extending with a new feature, add its env-var prefix to the whitelist tuple in lib/env.py:get_config().
| Pattern | Producer | Notes |
|---|---|---|
data_{date}.json |
tracking-list/collect.py | Source of truth for all downstream skills |
report_{date}.md |
morning-ai (Step 3) | Detailed daily report |
manifest_{date}.json |
gen-infographic | Image generation jobs |
social/{date}_*.md |
gen-social | Per-platform copy |
message_{date}.md / .png |
gen-message | Chat digest |
email_{date}.html / .txt |
gen-email | Local previews of sent emails |
email_{date}_manifest.json |
gen-email | Per-recipient send status |
- Skill versioning: bump every
version: "x.y.z"field inSKILL.mds +plugin.jsons +marketplace.jsontogether. Add a CHANGELOG entry. - Symlink:
skills/morning-ai/SKILL.mdis a symlink to rootSKILL.mdso Claude Code's skill scanner finds it. Edit the root file — both paths show the same content. - Date convention:
YYYY-MM-DDin UTC+8 (Asia/Shanghai). The 24-hour collection window is08:00 UTC+8 yesterday→08:00 UTC+8 today. - Sub-skill activation: each optional output channel is gated by an
*_ENABLED=trueenv var (MESSAGE_ENABLED,SOCIAL_ENABLED,EMAIL_ENABLED). Steps silently no-op when their gate is unset. - Script entry pattern: scripts under
skills/*/scripts/addsys.path.insert(0, str(Path(__file__).resolve().parents[3]))to importlib. - Stdlib only: do not introduce external dependencies. The project's portability across AI tool environments depends on this — anything more than
python3is friction.
python3 -m unittest discover tests -vFor end-to-end checks of an output channel, prefer dry-run modes (e.g. EMAIL_DRY_RUN=true) over hitting real services.