From dc934ddb6ad4b20839e8f838b97ff78a35b23b60 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Sat, 9 May 2026 21:04:23 -0700 Subject: [PATCH] feat(digg): rename to 'Digg' and bump per-cluster post limits (#372) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(digg): bump POSTS_PER_CLUSTER to 5 and render limit to 3 Match the per-item enrichment cap and inline-display cap used by the other sources (Reddit, HN, YouTube, TikTok, GitHub all use 5 fetched / 3 displayed). At the previous 3/2 caps the engine routinely truncated cluster context β€” a recent run on cli-printing-press lost the Jason Calacanis quote tweet entirely because the display cut off after Garry Tan's first two posts. * feat(digg): rename 'Digg AI 1000' to 'Digg' in user-facing strings Drop the 'AI 1000' suffix from the footer line, source label, inline quote attribution ('via Digg'), why_relevant, container, mock title, SKILL.md source list, and README sources table. Internal code comments and docstrings still reference the upstream Digg AI 1000 product. Bumps version to 3.2.1 and adds a CHANGELOG entry covering this rename and the POSTS_PER_CLUSTER / render-limit bumps from the prior commit. --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> --- .claude-plugin/marketplace.json | 2 +- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- CHANGELOG.md | 5 +++++ README.md | 2 +- pyproject.toml | 2 +- skills/last30days/SKILL.md | 8 ++++---- skills/last30days/scripts/lib/digg.py | 9 +++++---- skills/last30days/scripts/lib/normalize.py | 4 ++-- skills/last30days/scripts/lib/pipeline.py | 4 ++-- skills/last30days/scripts/lib/render.py | 16 ++++++++-------- 11 files changed, 31 insertions(+), 25 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 35deae8..b975d61 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -11,7 +11,7 @@ { "name": "last30days", "description": "Research any topic across Reddit, X, YouTube, TikTok, Instagram, Hacker News, Polymarket, GitHub, and 5+ more sources. AI agent scores by upvotes, likes, and real money - not editors.", - "version": "3.2.0", + "version": "3.2.1", "author": { "name": "Matt Van Horn", "url": "https://github.com/mvanhorn" diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 44fa7d6..86f7fb9 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "last30days", - "version": "3.2.0", + "version": "3.2.1", "description": "Research any topic across Reddit, X, YouTube, TikTok, Instagram, Hacker News, Polymarket, GitHub, and 5+ more sources. AI agent scores by upvotes, likes, and real money - not editors.", "author": { "name": "Matt Van Horn", diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 9efad9f..830c5b9 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "last30days", - "version": "3.2.0", + "version": "3.2.1", "description": "Research any topic across Reddit, X, YouTube, TikTok, Instagram, Hacker News, Polymarket, GitHub, and 5+ more sources. AI agent scores by upvotes, likes, and real money - not editors.", "author": { "name": "Matt Van Horn", diff --git a/CHANGELOG.md b/CHANGELOG.md index 6312970..b051bff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Rename "Digg AI 1000" to just "Digg" in user-facing output (footer line, source label, inline-quote suffix, why_relevant, container attribution). Internal references to the upstream Digg AI 1000 product remain in code comments and docstrings. +- Bump `POSTS_PER_CLUSTER` from 3 to 5 and the render-side display limit from 2 to 3 to match the per-source enrichment caps used by Reddit, HN, YouTube, TikTok, and GitHub. The previous 3/2 caps routinely truncated cluster context (e.g. dropped a Jason Calacanis quote tweet on a `cli-printing-press` run). + ## [3.2.0] - 2026-05-09 ### Added diff --git a/README.md b/README.md index ac211d4..3ed5c3e 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ If you're meeting with a CEO, have you read all their tweets and YouTube transcr | **Hacker News** | The developer consensus. 825 points, 899 comments. Where technical people actually argue. | | **Polymarket** | Not opinions. Odds. Backed by real money. 96% confidence on album sales. 4% on an acquisition. | | **GitHub** | For people: PR velocity, top repos by stars, release notes. For topics: issues and discussions. | -| **Digg AI 1000** | Curated story clusters from ~1000 high-signal AI accounts on X, with attributable inline quotes (no X auth required). Auto-enabled when `digg-pp-cli` is on PATH. | +| **Digg** | Curated story clusters from Digg's AI 1000 leaderboard (~1000 high-signal AI accounts on X), with attributable inline quotes (no X auth required). Auto-enabled when `digg-pp-cli` is on PATH. | | **Threads** | The post-Twitter text layer. Conversations from creators and brands. | | **Pinterest** | Visual discovery. Pins, saves, and comments on products and ideas. | | **Bluesky** | The decentralized social layer. AT Protocol posts from the post-Twitter migration. | diff --git a/pyproject.toml b/pyproject.toml index 59768fc..b9a051a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "last30days-skill" -version = "3.2.0" +version = "3.2.1" description = "Multi-source last-30-days research skill" readme = "README.md" requires-python = ">=3.12" diff --git a/skills/last30days/SKILL.md b/skills/last30days/SKILL.md index 0b2cc96..a7db05f 100644 --- a/skills/last30days/SKILL.md +++ b/skills/last30days/SKILL.md @@ -1,6 +1,6 @@ --- name: last30days -version: "3.2.0" +version: "3.2.1" description: "Research what people actually say about any topic in the last 30 days. Pulls posts and engagement from Reddit, X, YouTube, TikTok, Hacker News, Polymarket, GitHub, and the web." argument-hint: 'last30days nvidia earnings reaction | last30days AI video tools | last30days what users want in react' allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch @@ -234,7 +234,7 @@ If your Bash call to `last30days.py` does NOT include the FULL pre-flight checkl --- -# last30days v3.2.0: Research Any Topic from the Last 30 Days +# last30days v3.2.1: Research Any Topic from the Last 30 Days > **Permissions overview:** Reads public web/platform data and optionally saves research briefings to `LAST30DAYS_MEMORY_DIR` (defaults to `~/Documents/Last30Days`). X/Twitter search uses optional user-provided tokens (AUTH_TOKEN/CT0 env vars). Bluesky search uses optional app password (BSKY_HANDLE/BSKY_APP_PASSWORD env vars - create at bsky.app/settings/app-passwords). All credential usage and data writes are documented in the [Security & Permissions](#security--permissions) section. @@ -318,7 +318,7 @@ Common patterns: - Always active: Reddit, Hacker News, Polymarket - If gh CLI is installed (check `which gh`): add GitHub -- If digg-pp-cli is installed (check `which digg-pp-cli`): add Digg AI 1000 +- If digg-pp-cli is installed (check `which digg-pp-cli`): add Digg - If AUTH_TOKEN/CT0 or XAI_API_KEY or FROM_BROWSER is set, or xurl CLI is installed and authenticated: add X - If yt-dlp is installed (check `which yt-dlp`): add YouTube - If SCRAPECREATORS_API_KEY is set and INCLUDE_SOURCES contains tiktok: add TikTok @@ -826,7 +826,7 @@ Only show lines for platforms where something was resolved. Skip empty lines. On - For how_to: prioritize YouTube (tutorials) and Reddit (guides) - Primary subquery weight = 1.0, secondary = 0.6-0.8, peripheral = 0.3-0.5 -**Available sources (include ALL in primary subquery):** reddit, x, youtube, tiktok, instagram, hackernews, polymarket. Optional: bluesky, truthsocial, threads, pinterest, grounding (web search - only if user has Brave/Exa/Serper key), digg (Digg AI 1000 clusters - only if `digg-pp-cli` is on PATH) +**Available sources (include ALL in primary subquery):** reddit, x, youtube, tiktok, instagram, hackernews, polymarket. Optional: bluesky, truthsocial, threads, pinterest, grounding (web search - only if user has Brave/Exa/Serper key), digg (Digg clusters - only if `digg-pp-cli` is on PATH) **Intent β†’ freshness_mode mapping:** - breaking_news, prediction β†’ `strict_recent` diff --git a/skills/last30days/scripts/lib/digg.py b/skills/last30days/scripts/lib/digg.py index 492eb8d..ea03689 100644 --- a/skills/last30days/scripts/lib/digg.py +++ b/skills/last30days/scripts/lib/digg.py @@ -44,8 +44,9 @@ ENRICH_CONFIG = { "deep": 5, } -# X posts pulled per enriched cluster. -POSTS_PER_CLUSTER = 3 +# X posts pulled per enriched cluster. Matches the 5-comment cap used by +# Reddit/HN/YouTube/TikTok/GitHub enrichment. +POSTS_PER_CLUSTER = 5 SEARCH_TIMEOUT = 30 POSTS_TIMEOUT = 15 @@ -285,9 +286,9 @@ def parse_digg_response( "posts": [], "relevance": round(relevance, 2), "why_relevant": ( - f"Digg AI 1000 cluster (rank {rank}, {post_count} posts, {unique_authors} authors)" + f"Digg cluster (rank {rank}, {post_count} posts, {unique_authors} authors)" if rank is not None - else f"Digg AI 1000 cluster ({post_count} posts, {unique_authors} authors)" + else f"Digg cluster ({post_count} posts, {unique_authors} authors)" ), } ) diff --git a/skills/last30days/scripts/lib/normalize.py b/skills/last30days/scripts/lib/normalize.py index c3cb6aa..214119f 100644 --- a/skills/last30days/scripts/lib/normalize.py +++ b/skills/last30days/scripts/lib/normalize.py @@ -412,7 +412,7 @@ def _normalize_digg( Each cluster is one item. The TLDR carries the most useful body for rerank and synthesis. Top-ranked X posts attached at search time are passed through under metadata['posts'] so render can emit them as - inline 'via Digg AI 1000' quotes. + inline 'via Digg' quotes. """ title = str(item.get("title") or "").strip() tldr = str(item.get("tldr") or "").strip() @@ -428,7 +428,7 @@ def _normalize_digg( body=body, url=str(item.get("url") or f"https://di.gg/ai/{cluster_url_id}"), author="", - container="Digg AI 1000", + container="Digg", published_at=item.get("date"), date_confidence=_date_confidence(item, from_date, to_date, default="high"), engagement=item.get("engagement") or {}, diff --git a/skills/last30days/scripts/lib/pipeline.py b/skills/last30days/scripts/lib/pipeline.py index 5c04c6b..ebedd45 100644 --- a/skills/last30days/scripts/lib/pipeline.py +++ b/skills/last30days/scripts/lib/pipeline.py @@ -538,7 +538,7 @@ def _finalize_items_by_source( if source == "digg" and items: # Pull top-ranked X posts only for the survivors that will appear # in the brief. Spending the enrichment budget here (rather than - # at retrieval time) keeps the inline 'via Digg AI 1000' quotes + # at retrieval time) keeps the inline 'via Digg' quotes # paired with the clusters dedupe actually kept. digg.enrich_source_items(items, top_k=3) finalized[source] = items @@ -1078,7 +1078,7 @@ def _mock_stream_results(source: str, subquery: schema.SubQuery) -> tuple[list[d "digg": [ { "id": "mock1abc", - "title": f"Digg AI 1000 cluster about {subquery.search_query}", + "title": f"Digg cluster about {subquery.search_query}", "url": "https://di.gg/ai/mock1abc", "tldr": f"Curated cluster summarizing recent {subquery.search_query} discussion across the AI 1000.", "author": "", diff --git a/skills/last30days/scripts/lib/render.py b/skills/last30days/scripts/lib/render.py index 79b926b..fdd24f8 100644 --- a/skills/last30days/scripts/lib/render.py +++ b/skills/last30days/scripts/lib/render.py @@ -53,7 +53,7 @@ SOURCE_LABELS = { "xiaohongshu": "Xiaohongshu", "x": "X", "github": "GitHub", - "digg": "Digg AI 1000", + "digg": "Digg", "perplexity": "Perplexity", } @@ -853,7 +853,7 @@ def render_full(report: schema.Report) -> str: tc_score = tc.get("score", "") attribution = _comment_attribution(item.source, tc.get("author")) lines.append(f" Top comment {attribution} ({tc_score} {vote_label}): {excerpt}") - # Digg AI 1000: inline X-post quotes attached to the cluster. + # Digg: inline X-post quotes attached to the cluster. for post in _digg_posts_for(item, limit=3): lines.append(f" > {_format_digg_quote(post)}") # Comment insights for Reddit @@ -1229,7 +1229,7 @@ _FOOTER_SOURCES: list[tuple[str, str, str, str, list[tuple[str, str]]]] = [ ("bluesky", "πŸ¦‹", "Bluesky", "post", [("likes", "likes"), ("reposts", "reposts")]), ("truthsocial", "πŸ‡ΊπŸ‡Έ", "Truth Social", "post", [("likes", "likes"), ("reposts", "reposts")]), ("github", "πŸ™", "GitHub", "item", [("reactions", "reactions"), ("comments", "comments")]), - ("digg", "⛏️", "Digg AI 1000", "cluster", [("postCount", "posts"), ("uniqueAuthors", "authors")]), + ("digg", "⛏️", "Digg", "cluster", [("postCount", "posts"), ("uniqueAuthors", "authors")]), ] @@ -1684,7 +1684,7 @@ def _comment_insight(item: schema.SourceItem | None) -> str | None: return str(insights[0]).strip() or None -def _digg_posts_for(item: schema.SourceItem | None, limit: int = 2) -> list[dict]: +def _digg_posts_for(item: schema.SourceItem | None, limit: int = 3) -> list[dict]: """Return up to `limit` parsed Digg posts attached as enrichment to a cluster. Returns an empty list for non-digg sources or clusters without enrichment. @@ -1704,17 +1704,17 @@ def _digg_posts_for(item: schema.SourceItem | None, limit: int = 2) -> list[dict def _format_digg_quote(post: dict, body_limit: int = 200) -> str: - """Format a Digg-attached X post as an inline 'via Digg AI 1000' quote line.""" + """Format a Digg-attached X post as an inline 'via Digg' quote line.""" handle = post.get("username") or "" x_url = post.get("x_url") or "" body = (post.get("body") or "").replace("\n", " ").strip() if len(body) > body_limit: body = body[: body_limit - 1].rstrip() + "…" if x_url and handle: - return f"[@{handle}]({x_url}) via Digg AI 1000: {body}" + return f"[@{handle}]({x_url}) via Digg: {body}" if handle: - return f"@{handle} via Digg AI 1000: {body}" - return f"via Digg AI 1000: {body}" + return f"@{handle} via Digg: {body}" + return f"via Digg: {body}" def _transcript_highlights(item: schema.SourceItem | None) -> list[str]: