AI-powered agent that collects GitHub traffic data, reads it with Claude, and sends you a phone-sized brief you can act on -- solving the 14-day data retention limit.
A notification that fits a phone lock screen:
π navox/repo: clones +38% WoW (52β72), mostly from HN.
β’ Add a 30-sec quickstart to the README.
β’ Drop the HN thread link in your next release notes.
Last tip (onboarding) β clones +22%. Keep going.
That's it. No dashboards, no walls of text. The agent collects data daily, and when you ask for a report, Claude reads everything and writes the one message that matters.
As a solo founder who is also a builder, I can't live without my AI agents. I built my own team of agents to help me take my concepts from start to finish, while I handle my own marketing, posting, and blogging across many channels.
One of the most important signals that drives my product decisions is repo traffic. I build in public, open-source, and solo -- so monitoring traffic and paying attention to trends is a critical part of product development.
I use GitHub, and unfortunately GitHub only keeps and displays 2 weeks of traffic data. I really wish I had built this agent earlier. I remember when my network repo approached 1,000 clones in a single day, but I just didn't keep any record of it. Plus, I only discovered GitHub Insights traffic recently.
I didn't want this agent to just be a data collector. I wanted a proactive, fully experienced data scientist agent that collects, analyzes, predicts, and proposes -- and sends me a notification just in case I've got my hands busy somewhere else.
The data pipeline is deterministic and tested -- the LLM never writes, edits, or computes stored numbers. It only reads validated outputs and writes prose.
- Collect -- Fetches views, clones, paths, and referrers from the GitHub API
- Validate -- Checks schema, completeness, continuity; warns on zero-data or gaps
- Store -- Merges with existing data, deduplicates by date, atomic writes
- Notify -- Sends collection digest to configured channels
- Analyze -- Computes 7-day and 30-day trends, detects anomalies (z-score)
- Predict -- Forecasts next 14 days (moving average + linear regression blend)
- Propose -- Generates rule-based recommendations from patterns
- Intelligence -- Claude reads all of the above and writes a Brief (or falls back to rules)
- Report -- Commits a full Markdown report as an artifact
- Notify -- Sends the Brief to Slack, Telegram, and/or email (each rendered natively)
Each Brief's actions are persisted. Next report, the agent passes prior actions + traffic-since to Claude, which judges in one line whether the advice tracked. The agent grades its own advice.
Traffic data is private by design -- GitHub restricts it to repo admins. The agent stores all data in a separate private repo you control, so it's never exposed even if your monitored repos are public.
Create a private repo (e.g. my-org/traffic-data):
gh repo create my-org/traffic-data --privateThe agent needs a Personal Access Token to read traffic data and write to your data repo.
- Go to GitHub Settings > Fine-grained tokens
- Create a token with Repository access for your target repo(s) and your data repo
- Grant Read and write permission for Contents and Read-only for Metadata
- Alternatively, use a classic token with
reposcope
Add it as a repository secret:
gh secret set TRAFFIC_TOKENCreate .github/workflows/traffic.yml in the repo you want to monitor:
name: GitHub Traffic Agent
on:
schedule:
- cron: '0 3 * * *' # Daily collection at 3 AM UTC
- cron: '0 4 1,15 * *' # Bi-weekly reports on 1st and 15th
workflow_dispatch:
inputs:
mode:
description: 'Run mode'
default: 'collect'
type: choice
options: [collect, report]
jobs:
traffic:
runs-on: ubuntu-latest
steps:
- uses: navox-labs/github-traffic-agent@v1
with:
token: ${{ secrets.TRAFFIC_TOKEN }}
data_repo: my-org/traffic-data # your private data repo
mode: ${{ github.event.schedule == '0 4 1,15 * *' && 'report' || github.event.inputs.mode || 'collect' }}How the mode expression works: When the 1st/15th cron fires, mode is set to
report. For the daily cron or manual dispatch, it uses the selected mode (defaulting tocollect).
Monitoring multiple repos? Use the same
data_repoacross all your workflows. Each monitored repo gets its own subfolder automatically.
Trigger the first collection manually:
gh workflow run traffic.yml -f mode=collectThe agent will collect your traffic data and commit it to your private data repo. Let it run daily for a few days to build up history, then trigger a report:
gh workflow run traffic.yml -f mode=reportThat's it -- the agent is now collecting daily and reporting bi-weekly on autopilot. Your traffic data stays private.
For Claude-powered analysis instead of rule-based summaries, add your Anthropic API key:
gh secret set ANTHROPIC_API_KEYThen add it to your workflow:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}Without an API key, the agent still works -- it falls back to deterministic rule-based summaries. The AI layer is optional but recommended.
Send briefs and collection digests to Slack, Telegram, and/or email. Add any combination:
notify_slack: ${{ secrets.SLACK_WEBHOOK }}
notify_telegram: ${{ secrets.TELEGRAM_CONFIG }} # bot_token:chat_id
notify_email: ${{ secrets.EMAIL_CONFIG }} # JSON stringSlack setup: Create an Incoming Webhook and store the URL as SLACK_WEBHOOK.
Telegram setup: Create a bot via @BotFather, get your chat ID, and store as bot_token:chat_id in TELEGRAM_CONFIG.
Give Claude context about your project for smarter, more relevant briefs:
product_context: '{"description": "CLI tool for managing Docker containers", "audience": "DevOps engineers"}'| Input | Required | Default | Description |
|---|---|---|---|
token |
Yes | -- | GitHub PAT with repo scope |
data_repo |
Yes | -- | Private repo to store traffic data (owner/repo) |
repos |
No | current repo | Comma-separated owner/repo list to monitor |
data_dir |
No | traffic-data/ |
Directory for data files within data repo |
branch |
No | default branch | Branch to commit data to |
mode |
No | collect |
collect or report |
anthropic_api_key |
No | -- | Anthropic API key for AI briefs |
model |
No | claude-sonnet-4-20250514 |
Claude model ID |
product_context |
No | -- | JSON with description and audience |
notify_slack |
No | -- | Slack webhook URL |
notify_telegram |
No | -- | bot_token:chat_id format |
notify_email |
No | -- | SMTP config as JSON string |
All data is stored in your private data repo, organized by monitored repo:
your-private-data-repo/
traffic-data/
owner/repo-name/ # One folder per monitored repo
memory/
views.json # Historical daily views
clones.json # Historical daily clones
paths/ # Daily popular paths snapshots
referrers/ # Daily popular referrers snapshots
audit-log.json # Run audit log
brief-actions.json # Persisted actions for feedback loop
reports/
YYYY-MM-DD-report.md # Analysis reports
exports/
YYYY-MM-DD_to_YYYY-MM-DD-traffic.csv # Bi-weekly CSV snapshots
- Deterministic data spine. The LLM never writes, edits, or computes stored numbers. Collection, merge/dedup, storage, and stats are deterministic and tested.
- Output is short by contract. Headline max 15 words, max 2 actions at 12 words each. Enforced in code, not by prompt hope.
- LLM is non-fatal. On API error or invalid JSON, falls back to a terse rule-based message. The agent never crashes or goes silent because the model failed. A health token surfaces when the LLM layer is degraded.
- Each channel renders natively. Slack gets plain text, Telegram gets markdown, email gets subject/body split.
# Install
pip install -e ".[dev]"
# Tests (66 tests)
pytest tests/ -v
# Lint
ruff check src/ tests/
# Type check
mypy src/MIT