* 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>
34 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[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_CLUSTERfrom 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 acli-printing-pressrun).
[3.2.0] - 2026-05-09
Added
- Add
--emit=htmlfor shareable, print-friendly HTML research briefs. - Digg AI 1000 source (auto-enabled when
digg-pp-cliis on PATH). Surfaces curated story clusters from the AI 1000 leaderboard and pulls attributable X-post quotes into the brief as[@handle](xUrl) via Digg AI 1000: ...lines. Footer line:⛏️ Digg AI 1000: N clusters │ K posts │ M authors. No X auth required for the inline quotes since they flow through Digg's read-only endpoints.
[3.1.1] - 2026-04-24
Fixed
- Codex plugin layout. Move the canonical runtime payload under
skills/last30days/and update Codex/Claude plugin metadata and tests for the relocated engine path. - Claude Code cache resolution. Resolve Claude plugin installs to
skills/last30days/scripts/last30days.pyafter the plugin-layout restructure.
[3.1.0] - 2026-04-22
Consolidates the 3.0.10 to 3.0.14 dev cycle (commenter handles, --competitors, per-entity Step 0.55, vs-mode N passes, comparison title attribution) and republishes the OpenClaw bundle, which had been frozen on ClawHub at 3.0.0-open since April 8.
Added
- OpenClaw republish.
clawhub install last30days-officialnow resolves to3.1.0-open, matching current main. Closes #307, #195, #236. The ClawHub bundle had shipped a brokenenv.py get_config()and stale SKILL.md path references since April; both are fixed at source on main and the republish carries the fixes to installers.
Fixed
- Claude Code plugin manifest path-escape. The
.claude-plugin/plugin.jsonskillskey was removed in commit93fbed2but never shipped in a tagged release. Installing via/plugin install last30days-skillcould hit/doctor'sPath escapes plugin directory: ./ (skills)error. This release ships the fix. Closes #306. - Broken README link. The README's "source of truth" link pointed at
skills/last30days/SKILL.md, a path that does not exist. Fixed to point at rootSKILL.md.
Dev cycle journal (3.0.10 - 3.0.14, not separately tagged)
Individual changelog entries for 3.0.10 through 3.0.14 below document the incremental work consolidated into this release.
[3.0.14] - 2026-04-22
Changed
- Comparison-mode title attribution. The synthesis title for vs-mode and
--competitorsoutputs changes fromWhat the Community Says (Last 30 Days)toWhat the Community Says (/Last30Days). Surfaces the slash-command identity instead of restating the date range. Three SKILL.md occurrences updated; pure documentation change.
[3.0.13] - 2026-04-22
Changed
- vs mode runs N full passes in parallel, one per entity. Architectural revert of the 3-pass → 1-pass latency optimization from an earlier version.
/last30days "OpenAI vs Anthropic vs xAI"now runs three fullpipeline.run()calls in parallel via the same fanout--competitorsuses, producing three*-raw.mdsave files plus a merged comparison output. Each entity gets its own Step 0.55-grade targeting, own primary X handle weight, own subreddit scoping — apples-to-apples depth instead of the one-pool merged retrieval the single-pass path produced. Parallel execution keeps wall clock ≈ single pass. --competitorsis now a SKILL.md-level shortcut for vs-mode with auto-discovery. The hosting reasoning model (Claude Code, Codex, Hermes, Gemini, any agent with WebSearch) performs discovery and Step 0.55 per entity via its own WebSearch tool, then invokes the engine with a vs-topic and--competitors-planJSON. The engine flag remains for headless/cron use with BRAVE/EXA/SERPER/PARALLEL/OPENROUTER keys (engine-internalauto_resolvestays as fallback).- LAW 7-style stderr for
--competitorswith no backend now leads with the hosting-model path (WebSearch + Step 0.55 +--competitors-plan) instead ofBRAVE_API_KEY. API-key framing moved to a secondary "headless" section.
Added
--competitors-planJSON flag for per-entity Step 0.55 targeting. Schema:{entity_name: {x_handle?, x_related?, subreddits?, github_user?, github_repos?, context?}}. Accepts inline JSON or a file path (matches--plan). When present for an entity, skips engine-internalauto_resolveand uses the provided values; missing fields fall back toauto_resolve(if backend) or planner defaults. Case-insensitive entity matching. Thesubrun_kwargs_forhelper is the single source of truth for per-entity kwargs — no closure-default fallthrough from main scope.- Per-entity save files when
--save-diris set on a vs-mode or--competitorsrun. Each entity's sub-run produces its own{slug}-raw.mdwith a single-row Resolved Entities block — matches historical vs-mode behavior (N passes → N save files). --polymarket-keywords "kw1,kw2"to filter Polymarket matches for ambiguous single-token topics (e.g., "Warriors" →nba,gsw,golden-statekills Glasgow Warriors rugby and Honor of Kings Rogue Warriors noise).
Fixed
- BRAVE/SERPER footer nudge suppressed when
--planor--competitors-planis present. The nudge told Claude Code users to set an API key when they already have WebSearch via the hosting model. Nudge still fires for true headless runs (no--plan, no backend) where the advice is correct. - Override-leak regression testing. 3.0.12 already fixed the main-topic
--subreddits/--x-handle/--github-*from leaking into peer sub-runs via explicit per-entity kwargs scrubbing. This release adds a 4-test regression suite (test_competitor_subrun_isolation.py) locking in the invariant.
[3.0.12] - 2026-04-22
Fixed
- Per-entity Step 0.55 resolution for competitor sub-runs. In 3.0.11, only the main topic got X handle / subreddit / GitHub resolution; competitor sub-runs ran with planner defaults and produced visibly thinner evidence (Reddit 403 fallbacks, single-word queries). Each competitor sub-run now calls
resolve.auto_resolve()insidefanout.run_competitor_fanoutwhen a web backend is available, mirroring the main topic's pre-flight resolution. Per-entity X handle, subreddit list, GitHub user/repos, and news context are threaded into each sub-run'spipeline.run()call. Deep-copied config per sub-run prevents_auto_resolve_contextcross-leak. Surfaces in a new## Resolved Entitiesoutput block so the resolution coverage is visible without reading stderr. - LAW 7 false-positive on internal fan-out sub-runs. Each competitor sub-run was emitting the
[Planner] No --plan passed... YOU ARE the plannerstderr warning. LAW 7 targets the hosting-reasoning-model path, not engine-internal fan-out. Newinternal_subrun=Truekeyword onplanner.plan_queryandpipeline.runsuppresses the warning for sub-runs only; the default path is unchanged. - Marketplace-stale SKILL.md trap. Added a STEP 0 canonical-path self-check at the top of SKILL.md. Two of three 2026-04-22 test runs loaded SKILL.md from
plugins/marketplaces/last30days-skill/(Claude-Code-managed git clone pinned to origin/main, lagging the versioned cache), then ran--helpagainst the same stale path, did not see--competitors, and fell back to a manual comparison plan. The STEP 0 block forces any reader to verify they loaded fromplugins/cache/last30days-skill/last30days/{VERSION}/SKILL.mdand re-read from the versioned cache if not.
Changed
- Default
--competitorscount is now 2 (3-way total: original + 2 peers). Previously 3.--competitors=Nstill customizes (range 1..6). Matches the feature description's canonical example (Kanye vs Drake vs Kendrick).
Added
## Resolved Entitiesblock inrender_comparison_multioutput. Shows per-entity X handle, subreddits, GitHub user/repos, and truncated context for every entity in the comparison. Block is omitted entirely when no entity has a resolved payload (mock mode, no backend).
[3.0.11] - 2026-04-22
Added
--competitorsflag for auto-discovered comparison fan-out. Pass--competitorson a single-entity topic and the engine discovers 2-6 peer entities via web search, then runs the full pipeline on each in parallel and emits one N-way comparison.last30days Kanye West --competitorsresolves Drake, Kendrick Lamar, and one more peer.last30days OpenAI --competitorsresolves Anthropic, xAI, Google Gemini.--competitors=Ncontrols count,--competitors-list="A,B,C"skips discovery and uses the explicit list. Discovery mirrors theauto_resolvepattern (Brave / Exa / Serper / Parallel) with deterministic text extraction - no internal LLM call. Sub-runs inherit the main--quick/--deep/--days, run in aThreadPoolExecutor, and degrade gracefully when at least 2 entities survive. Output reuses the existing 9-axis## Head-to-Headscaffold.
[3.0.10] - 2026-04-21
Added
- Commenter handles on evidence lines. Top-comment rendering now includes the commenter's handle -
u/authorfor Reddit,@handlefor TikTok/YouTube/Instagram/Bluesky/X/Threads. The enrichment adapters already capturedauthor; the render layer just was not using it. Evidence lines change from- Comment (6822 upvotes): Finally, John Appleto- u/Cyrisaurus (6822 upvotes): Finally, John Apple. Person-level citations make synthesis-side inline markdown links per LAW 8 much more natural. Both the compact and full render paths are covered.
Fixed
- TikTok author preference.
_fetch_post_commentsinscripts/lib/tiktok.pypreferreduser.nicknameoveruser.unique_id, so the engine captured display names ("Moosa Noormahomed") instead of @handles ("moosanoormahomed"). Flipped to preferunique_id. Nickname still wins as a fallback whenunique_idis missing. Display names can contain emoji, spaces, and non-Latin characters that do not round-trip to a profile URL; the @handle is the stable identifier. - Single plugin payload layout. The canonical runtime moved to
skills/last30days/for both Claude Code and Codex plugin loading. Root-levelSKILL.md,scripts/,agents/, andassets/are no longer maintained as duplicate copies.
Behavior fallback
- When an author is empty,
[deleted], or[removed], the render falls back to the legacyComment (...)shape - nou/or@prefix with an empty handle is ever emitted.
3.0.9 - 2026-04-18 - The Self-Debug Release
Highlights
v3.0.9 adds the engine-side Class 1 keyword-trap refuse-gate ("birthday gift for 40 year old" now gets a clarifying question, not 5 minutes of junk), promotes TikTok and YouTube top comments to the same first-class rendering Reddit's got, lands Hermes AI Agent as a first-class deploy target, and moves the SKILL.md formatting contract from line 1094 to the top of the file.
"The Self-Debug Release" refers to how the fixes in 3.0.6-3.0.9 were written: 5 separate Opus 4.7 instances each debugged their own failed outputs. Three converged on "SKILL.md is too big and the LAWs are too deep." Two converged on "the engine should refuse demographic-shopping queries." I shipped exactly what they said. Validation: 5/5 canonical compliance.
Added
- Engine Class 1 keyword-trap refuse-gate (
scripts/lib/preflight.py, new). Pattern-matches demographic-shopping queries at main() front-door. Exit code 2 with structured REFUSE message. Escape hatch:LAST30DAYS_SKIP_PREFLIGHT=1. 29 tests intests/test_preflight.py. - TikTok + YouTube top comments rendered with same
💬 Top commentprominence as Reddit's. Shipped in #260; enrichment fixed in #265. - Hermes AI Agent as a deploy target - thanks @stephenmcconnachie (#228).
scripts/sync.shdetects~/.hermes/skills/researchand deploys automatically. - Multi-key SCRAPECREATORS_API_KEY rotation - thanks @zaydiscold (#268). Set
SCRAPECREATORS_API_KEY_1,_2, etc. Engine rotates on rate-limit. - Offline quality evaluation fixture - thanks @j-sperling (#233).
eval_topics.jsonlets contributors run quality regressions without burning live API credits. - END-OF-CANONICAL-OUTPUT boundary in
render_compact(). Engine now emits an explicit pass-through instruction so re-synthesis requires actively ignoring a visible boundary. - LAW 1 verbatim-pattern override. LAW 1 now quotes the exact WebSearch tool-result reminder ("CRITICAL REQUIREMENT: MUST include Sources: section") and declares it OVERRIDDEN inside last30days output.
Changed
- SKILL.md restructure. VOICE CONTRACT LAWs and BADGE MANDATORY block moved from line 1094 to lines 75-150. Grounded in 3 separate Opus 4.7 self-debugs.
- Engine emits the badge as stdout.
🌐 last30days v3.0.9 · synced YYYY-MM-DDis the first line of every compact emit. Pass-through is now the default-correct behavior. - Reddit client HTTP consolidation - thanks @iliaal (#207). Migrated to
http.get(params=...)helper. - ScrapeCreators header consolidation - thanks @iliaal (#209).
_sc_headersrefactored intohttp.scrapecreators_headers. - Simpler Hermes sync.
scripts/sync.shHermes branch now always uses main SKILL.md (previously had a.hermes-plugin/SKILL.mdfallback that created a wrong-file-capture hazard).
Fixed
- Peter Steinberger trailing Sources leak. 2026-04-18 validation failure where the model appended a TechCrunch / TED / Fortune / Wikipedia Sources list after the invitation. Now structurally prevented at three layers: engine emits the canonical body, LAW 1 quotes the exact WebSearch reminder, closing boundary names the anti-pattern.
- Wrong-file SKILL.md capture. Deleted
.agents/skills/last30days/SKILL.md(1382 lines, April 13 snapshot) and.hermes-plugin/SKILL.md(269 lines). One SKILL.md per plugin now, at the plugin root. - GitHub date parsing garbage - thanks @iliaal (#208).
_parse_datenow rejects invalid input cleanly. - Windows Bird X stability - thanks @Chelebii (#227).
- Linux
check_permsfalse-warn - thanks @george231224 (#216). Uses GNU stat first. - UTF-8 saved output - thanks @Gujiassh (#225).
- Version metadata alignment - thanks @Gujiassh (#217) and @shalomma (#229).
--daysalias backcompat - thanks @BryanTegomoh (#230).INCLUDE_SOURCESenv default - thanks @hnshah (#223).- Bird X all-None engagement - thanks @j-sperling (#234).
Contributors
@j-sperling, @stephenmcconnachie, @zaydiscold, @iliaal, @Chelebii, @Gujiassh, @hnshah, @george231224, @shalomma, @BryanTegomoh for PRs since v3.0.0. @uppinote20, @zerone0x, @thinkun, @thomasmktong, @fanispoulinakisai-boop, @pejmanjohn, @zl190, @Jah-yee, @dannyshmueli, @Cody-Coyote for issues and PRs that shaped the v3 roadmap.
Recovery
/plugin update last30days
/reload-plugins
Verify: cat ~/.claude/plugins/cache/last30days-skill/last30days/*/.claude-plugin/plugin.json | grep version returns "version": "3.0.9".
Smoke test: /last30days birthday gift for 40 year old should ask a clarifying question before running.
[3.0.5] - 2026-04-15
Added
/last30daysslash command for plugin users. Newcommands/last30days.mdregisters a Claude Code slash command. Users type/last30days <topic>and Claude Code's autocomplete prefix-matches it to the canonical/last30days:last30daysform (the same way/ce:planresolves to/compound-engineering:ce-plan). The command delegates to the existinglast30daysskill body — no skill behavior changes.
Removed
skills/last30days-nux/— byte-identical duplicate of rootSKILL.mdthat created confusing/last30days:last30days-nuxautocomplete entries via Claude Code's plugin namespacing. The rootSKILL.mdremains the canonical skill source.
Recovery
/plugin update last30days
/reload-plugins
Then type /last30days <topic> to invoke the skill via slash command. Natural-language invocation ("search the last 30 days for X") continues to work unchanged.
[3.0.4] - 2026-04-15
Fixed
- Cleared
/doctorpath-escape error on Claude Code v2.1.109+..claude-plugin/plugin.jsonpreviously declared"skills": ["./"]. That value shipped unchanged from v2.1.0 through v3.0.3 and worked on older Claude Code, but current versions reject./withPath escapes plugin directory: ./ (skills). The"skills"key is now omitted entirely, matching the pattern used by every other plugin in the Claude Code marketplace ecosystem. Claude Code auto-discoversskills/*/SKILL.mdwhen the key is absent.
Recovery
If /doctor reports a path-escape error for last30days, run /plugin update last30days then /reload-plugins. If errors persist, uninstall and reinstall the plugin.
[3.0.3] - 2026-04-15
Fixed
- Restored
skills/and.claude-plugin/to the plugin install tarball. v3.0.1 added.gitattributesrules that excluded both directories fromgit archiveoutput to shrink the claude.ai.skillbundle. Claude Code's/plugin installfetches the same archive, so users installing v3.0.1 or v3.0.2 received a tarball with no plugin manifest and no skill files.git archive v3.0.0contained 8 files under those paths;v3.0.1andv3.0.2contained 0. This release reverts those.gitattributeslines. - Reverted
plugin.json"skills"field to["./"]. v3.0.2 changed this to["skills"]based on a misdiagnosis — the manifest change had no effect because the manifest wasn't in the tarball at all. The historical["./"]value shipped in every release from v2.1.0 through v3.0.0 without issues and is restored here.
Recovery
Users on v3.0.1 or v3.0.2: run /plugin update last30days then /reload-plugins. If autoUpdate is enabled, the next session start will pull v3.0.3 automatically. Users on cached v3.0.0 or earlier installs were unaffected.
Notes
- The claude.ai
.skillbundle built byscripts/build-skill.shstill works — the archive grew from 89 to 97 files, well under the 200-file cap. - claude.ai-specific exclusions (avoiding duplicate
SKILL.mdfiles in the bundle) should move intoscripts/build-skill.shrather than.gitattributesin a future release, since.gitattributescannot distinguish between the two distribution channels.
[3.0.2] - 2026-04-15
Fixed
/last30daysslash command now registers on Claude Code v2.1.105+..claude-plugin/plugin.jsondeclared"skills": ["./"], which newer Claude Code rejects withPath escapes plugin directory: ./ (skills). The skill silently failed to register, so/last30days <query>returned "Unknown command" even though/plugin listshowed the plugin as installed. Fix:"skills": ["skills"]so the loader scans the real skill subdirectory.- Version drift between manifests.
.claude-plugin/marketplace.jsonwas pinned to3.0.0while.claude-plugin/plugin.jsonadvertised3.0.1. The/pluginresolver used the marketplace version and could install stale cached metadata alongside the correct build. Both manifests now agree on3.0.2.
Recovery
If /last30days stopped working for you, run /plugin update last30days then /reload-plugins. If /doctor still reports errors, uninstall and reinstall the plugin from the marketplace.
[3.0.1] - 2026-04-14
Fixed
- Skill upload packaging -
scripts/build-skill.shproduces a claude.ai-upload-ready.skillfile that fits under the 200-file cap. Previously, zipping the repo hit 406 files and the "Upload skill" UI rejected it outright. - SKILL.md description length - trimmed from 228 to 167 chars (Anthropic caps descriptions at 200).
Removed
- Unused root
vendor/directory (215 files from an accidental commit in PR #48 - the real vendored X client lives atscripts/lib/vendor/bird-search/). - Legacy top-level
plans/directory (superseded bydocs/plans/; both plans described work that was already shipped in v3).
Added
.gitattributeswithexport-ignoreentries sogit archivedrops tests, docs, fixtures, assets, historical manifests, and internal skill subdirs. Mirrors Anthropic's canonicalpackage_skill.pyexclusions.scripts/build-skill.sh- one-command path to producedist/last30days.skillwith a single top-levellast30days/folder, defensive=200file check, and dirty-tree refusal.README.mdsection documenting the claude.ai skill upload workflow.
[3.0.0] - 2026-04-11
Highlights
Intelligent search, fun judge, cross-source cluster merging, single-pass comparisons, and OpenClaw as a first-class citizen. The v3 engine doesn't just search for your topic -- it figures out where to search before the search begins. Engine architecture by @j-sperling.
Added
- Intelligent pre-research -- Resolves X handles, subreddits, TikTok hashtags, and YouTube channels via a new Python brain before any API calls fire. Bidirectional: person to company, product to founder.
- Fun judge / Best Takes -- Second parallel LLM judge scores humor, cleverness, and virality. Surfaces the best reactions in a dedicated output section.
- Cross-source cluster merging -- Entity-based overlap detection merges the same story across Reddit, X, YouTube into one cluster instead of three separate items.
- Single-pass comparisons -- "X vs Y" runs one pass with entity-aware subqueries instead of three serial passes. 3 minutes instead of 12+.
- GitHub as a source -- Stars, reactions, and comments from repos and issues.
- OpenClaw first-class citizen -- Auto-resolve for engine-side pre-research. Device auth for frictionless ScrapeCreators signup.
- Per-author cap -- Max 3 items per author prevents single-voice dominance.
- Entity disambiguation -- Synthesis trusts resolved handles over keyword matches.
- Perplexity Sonar Pro as additive source -- AI-synthesized research with citations via OpenRouter. Opt-in via
INCLUDE_SOURCES=perplexity. Returns structured narratives that complement social data. - Perplexity Deep Research --
--deep-researchflag for exhaustive 50+ citation reports (~$0.90/query). Premium opt-in for serious investigation. - OpenRouter as reasoning provider -- One OPENROUTER_API_KEY powers planning, reranking, and Perplexity search. Auto-detected after Gemini/OpenAI/xAI.
- Parallel AI grounding backend --
--web-backend parallelor auto-detected via PARALLEL_API_KEY. - Grounding in planner -- Grounding source properly registered in SOURCE_CAPABILITIES instead of force-injected.
Changed
- YouTube transcript candidate pool widened 3x past music videos to reach talk/review content with captions
- Reddit comment enrichment sorted by total engagement (upvotes + comments), not just upvotes
- Polymarket display shows % odds only; dollar volumes removed
- 852 tests passing
Fixed
- Marketplace validation: duplicate
name: last30dayscollision inskills/last30days/SKILL.mdcaused strict validators to reject the plugin. Resolved by renaming the internal v3 architecture spec tolast30days-v3-specwithuser-invocable: false. Fixed in #214 (reported by @Cody-Coyote in #204). - Stale README link to the deleted
skills/last30days-v3/path from the v3 directory rename. Fixed in #214. - OpenAI Codex CLI discoverability: added
.agents/skills/last30days/SKILL.mdas a real file (Codex's loader skips symlinked files) plus.codex-plugin/plugin.jsonas the namespace marker. The skill now registers aslast30days:last30dayswhen Codex runs in a checkout of the repo. Fixed in #219 (inspired by @Jah-yee in #153 and @dannyshmueli on X).
Contributors
- @j-sperling -- v3 engine architecture, Python pre-research brain
- @hnshah -- Watchlist features
- @Cody-Coyote -- Marketplace validation bug report (#204)
- @Jah-yee -- Codex CLI integration inspiration (#153)
[2.9.4] - 2026-03-06
Changed
- Move save into Python script via
--save-dirflag - raw research data saved during the existing script Bash call, zero extra tool calls after invitation - Remove entire "Save Research to Documents" section from SKILL.md (~45 lines removed)
- No more
📎footer, no Bash heredoc, no(No output), no multi-minute cogitation after research
[2.9.3] - 2026-03-06
Fixed
- Critical: Switch save from
run_in_backgroundto foreground Bash - background callbacks caused model to re-engage, hallucinate fake user messages, and generate unsolicited multi-paragraph responses - Save uses foreground
cat >heredoc (executes sub-second, no callback, no delayed notification)
[2.9.2] - 2026-03-06
Fixed
- Save research silently using background Bash heredoc instead of Write tool (eliminates "Wrote N lines..." clutter)
- Suppress follow-up text after background save completes (no more "Research briefing saved..." noise)
- Add
📎footer line for save path instead of verbose confirmation
2.9.1 - 2026-03-05
Highlights
Auto-save research briefings to the default memory directory as topic-named .md files. Every run now builds a personal research library automatically - no more manual copy-paste.
Added
- Auto-save complete research briefings (synthesis, stats, follow-up suggestions) to the default memory directory after every run
- Kebab-case filename generation from topic (e.g., "Claude Code skills" ->
claude-code-skills.md) - Duplicate topic handling: appends date suffix instead of overwriting (e.g.,
claude-code-skills-2026-03-05.md) - Agent mode (
--agent) also saves research files - Brief confirmation after save with the saved file path
Credits
- @devin_explores -- Inspired this feature by sharing their workflow of saving every last30days run into organized .md files (PR #51)
2.9.0 - 2026-03-05
Highlights
ScrapeCreators Reddit as the default backend (one SCRAPECREATORS_API_KEY covers Reddit + TikTok + Instagram), smart subreddit discovery with relevance-weighted scoring, and top comments elevated with 10% scoring weight and prominent display.
Added
- ScrapeCreators Reddit backend (
scripts/lib/reddit.py) — keyword search, subreddit discovery, comment enrichment, all viaapi.scrapecreators.com - Smart subreddit discovery with relevance-weighted scoring: frequency × recency × topic-word match, replacing pure frequency count
UTILITY_SUBSblocklist to filter noise subreddits (r/tipofmytongue, r/whatisthisthing, etc.) from discovery results- Top comment scoring: 10% weight in engagement formula via
log1p(top_comment_score) - Top comment rendering:
💬 Top commentlines with upvote counts in compact and full report output - Comment excerpt length increased from 300 → 400 chars;
comment_insightslimit raised from 7 → 10
Changed
primaryEnvswitched fromOPENAI_API_KEYtoSCRAPECREATORS_API_KEY— one key now powers Reddit, TikTok, and Instagram- Reddit engagement scoring formula:
0.55/0.40/0.05(score/comments/ratio) →0.50/0.35/0.05/0.10(score/comments/ratio/top-comment) - SKILL.md synthesis instructions updated to emphasize quoting top comments
Fixed
- Utility subreddit noise in discovery (e.g., r/tipofmytongue appearing for unrelated topics)
- Reddit search no longer requires
OPENAI_API_KEY— ScrapeCreators API handles search directly
2.8.0 - 2026-03-04
Highlights
Instagram Reels as the 8th signal source, TikTok migrated from Apify to ScrapeCreators API, and SKILL.md quality improvements. One API key (SCRAPECREATORS_API_KEY) now covers both TikTok and Instagram.
Added
- Instagram Reels as 8th research source via ScrapeCreators API — keyword search, engagement metrics (views, likes, comments), spoken-word transcript extraction (
scripts/lib/instagram.py) InstagramItemdataclass, normalization, scoring (45% relevance / 25% recency / 30% engagement), deduplication, cross-source linking, and rendering- Instagram in SKILL.md: stats template (
📸 Instagram:), citation priority, item format description, output footer - URL-to-name extraction examples in SKILL.md for cleaner web source display
--search=instagramflag support
Changed
- TikTok backend migrated from Apify to ScrapeCreators API (
api.scrapecreators.com) APIFY_API_TOKENreplaced bySCRAPECREATORS_API_KEYin config- SKILL.md version bumped to v2.8
- WebSearch citation instruction strengthened to prevent trailing Sources: blocks
- Security section updated: Apify → ScrapeCreators references
Fixed
- Web stats line showing full URLs instead of plain domain names
- Trailing "Sources:" block appearing after skill invitation (WebSearch tool mandate conflict)
- Instagram/TikTok not running in web-only mode when
--search=instagramused without Reddit/X $ARGUMENTSquoting in SKILL.md for correct flag forwarding
2.1.0 - 2026-02-15
Highlights
Three headline features: watchlists for always-on bots, YouTube transcripts as a 4th source, and Codex CLI compatibility. Plus bundled X search with no external CLI needed.
Added
- Open-class skill with watchlists, briefings, and history modes (SQLite-backed, FTS5 full-text search, WAL mode) (
feat(open)) - YouTube as a 4th research source via yt-dlp -- search, view counts, and auto-generated transcript extraction (
feat: Add YouTube) - OpenAI Codex CLI compatibility -- install to
~/.agents/skills/last30days, invoke with$last30days(feat: Add Codex CLI) - Bundled X search -- vendored subset of Bird's Twitter GraphQL client (MIT, originally by @steipete), no external CLI needed (
v2.1: Bundle Bird X search) - Native web search backends: Parallel AI, Brave Search, OpenRouter/Perplexity Sonar Pro (
feat(engine)) --diagnoseflag for checking available sources and authentication status--storeflag for SQLite accumulation (open variant)- Conversational first-run experience (NUX) with dynamic source status (
feat(nux))
Changed
- Smarter query construction -- strips noise words, auto-retries with shorter queries when X returns 0 results
- Two-phase search architecture -- Phase 1 discovers entities (@handles, r/subreddits), Phase 2 drills into them
- Reddit JSON enrichment -- real upvotes, comments, and upvote ratio from reddit.com/.json endpoint
- Engagement-weighted scoring: relevance 45%, recency 25%, engagement 30% (log1p dampening)
- Model auto-selection with 7-day cache and fallback chain (gpt-4.1 -> gpt-4o -> gpt-4o-mini)
--days=Nconfigurable lookback flag (thanks @jonthebeef, #18)- Model fallback for unverified orgs (thanks @levineam, #16)
- Marketplace plugin support via
.claude-plugin/plugin.json(inspired by @galligan, #1)
Fixed
- YouTube timeout increased to 90s, Reddit 429 rate limit fail-fast
- YouTube soft date filter -- keeps evergreen content instead of filtering to 0 results
- Eager import crash in
__init__.pythat broke Codex environments - Reddit future timeout (same pattern as YouTube timeout bug)
- Process cleanup on timeout/kill -- tracks child PIDs for clean shutdown
- Windows Unicode fix for cp1252 emoji crash (thanks @JosephOIbrahim, #17)
- X search returning 0 results on popular topics due to over-specific queries
New Contributors
- @JosephOIbrahim -- Windows Unicode fix (#17)
- @levineam -- Model fallback for unverified orgs (#16)
- @jonthebeef --
--days=Nconfigurable lookback (#18)
Credits
- @galligan -- Marketplace plugin inspiration
- @hutchins -- Pushed for YouTube feature
1.0.0 - 2026-01-15
Initial public release. Reddit + X search via OpenAI Responses API and xAI API.