Commit Graph

125 Commits

Author SHA1 Message Date
Matt Van Horn 83c14209da fix: inline links on first pass, rebalance rule emphasis
Live test on Ghostty after the prior commit showed a regression: first-pass
/last30days synthesis stripped all inline links. Only after the user asked
"weren't these links supposed to be clickable?" did the agent re-render
with inline links. Agent's own root cause: "I misread LAW 1 — over-applied
'no trailing Sources: block' to mean 'no URLs anywhere'."

The templates and per-citation examples were already correct. The regression
was in EMPHASIS BALANCE — the anti-trailing-Sources prohibition used the
loudest prose (CRITICAL OVERRIDE, MANDATORY, MUST NOT) while the pro-inline-
link rule read as lighter guidance. On a fresh first read, the agent
collapsed both into one prohibition and stripped every citation link.

This commit rebalances emphasis and adds a forcing function:

- New "TWO HARD RULES FOR LINKS" framing at the top of the output section
  names RULE A (inline links required on every citation) and RULE B (no
  trailing list of links) as a matched pair with equal rhetorical weight.
  Explicit: "These rules are complementary, not alternatives."
- New "PRE-SYNTHESIS COMMIT" step forces the agent to identify sources,
  pull URLs, and commit to inline-link placement BEFORE drafting — not
  audit after the fact.
- Existing CRITICAL OVERRIDE block now opens by pointing back to the
  matched-pair framing and drops the "Your citation is the Web: line.
  Nothing else is needed." priming sentence that biased the agent toward
  link-free drafts.
- New BAD/ALSO-BAD/GOOD triple in the CRITICAL OVERRIDE block shows the
  exact regression shape (stripping inline links to "comply" with RULE B)
  as a distinct failure mode, not just the trailing-list failure.
- PRE-PRESENT SELF-CHECK reworked: item 6 becomes "RULE B — no trailing
  list", item 7 becomes "RULE A — inline links present on first pass"
  with a positive count check that regenerates if zero inline links
  appear when raw data had URLs (the exact 2026-04-20 regression repro).
- Release notes entry gains one line describing the first-pass guarantee.

No Python changes. This is an amendment on PR #286 folding the fix into
the same review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 07:24:56 -07:00
Matt Van Horn 38014f8143 feat: clickable source links in synthesis (no raw URLs)
Every cited source — X handles, subreddits, publications, YouTube channels,
Polymarket markets — now renders as a blue CMD-clickable markdown link in the
terminal. Raw URL strings remain forbidden everywhere in the output.

The old rule "NEVER paste raw URLs" blocked both raw URLs and links. Claude
Code renders CommonMark [text](url) as hyperlinks (URL hidden), so the new
rule is: "every link must be [text](url), never a raw URL string". Plain text
is the fallback only when the raw research dump has no URL for a source.

Changes:
- SKILL.md: invert URL formatting rule; update narrative / KEY PATTERNS /
  RECOMMENDATIONS / stats-block templates; retire the "I have all the links...
  Just ask." closer (it's now inline); add two new PRE-PRESENT SELF-CHECK
  items (no raw http/https strings, no broken empty links).
- README.md: note the clickable-links capability in the "How it works" list.
- release-notes.md: 2026-04-20 entry crediting @jay_k and @photomatt.

No Python changes — the raw research dump already carries URLs per item;
this is synthesis-side formatting only. No breaking changes to the engine,
the schema, or the CLI flags.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 00:24:56 -07:00
Matt Van Horn 73b4bd6ac6 fix: enforce pre-research protocol + override WebSearch Sources mandate (#266)
Restore the rich synthesis output by closing three prompt-level loopholes
that let the model silently take a degraded path:

1. Research Execution precondition gate. Steps 0.55 (entity resolution)
   and 0.75 (query planner) are now non-skippable on WebSearch platforms.
   --emit md is banned as a primary user-facing flow; --emit=compact with
   --plan is mandatory. OpenClaw --auto-resolve fallback preserved.

2. WebSearch "Sources:" mandate override. The WebSearch tool description
   contains a CRITICAL/MUST mandate to append a Sources section. That is
   explicitly superseded inside /last30days with matched-register
   CRITICAL/MANDATORY override language and a BAD/GOOD example. The
   existing web-source line is the citation; nothing appends below the
   invitation.

3. Pre-present self-check. Before displaying, the model verifies bold
   per-paragraph headlines, per-source emoji stats, quoted highlights,
   Polymarket block, coverage footer, and (critically) no trailing
   Sources block. One regeneration permitted if checks fail.

Also adds explicit MANDATORY language to the "What I learned" template
requiring bold headline phrases on every narrative paragraph.

Root cause: same-session A/B on 2026-04-15 between /last30days kanye
west (rich output, ran Steps 0.55 + 0.75, --emit=compact --plan) and
/last30days hermes ai (bland output, skipped both, --emit md) showed
the template was fine -- the model was lazily taking a shortcut SKILL.md
tolerated. No engine, render.py, or contributor PR was the cause.

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:15:29 -04:00
Matt Van Horn 082efe03e3 feat: surface YouTube + TikTok top comments alongside Reddit (#260)
* feat(normalize): pass YouTube top_comments through with Reddit-compatible shape

_normalize_youtube silently dropped top_comments after enrich_with_comments
populated them, so the downstream signals/render/entity layers never saw
YouTube comments. Map likes->score and text->excerpt so the existing
Reddit-compatible readers Just Work.

Shared _remap_comments helper will be reused for TikTok in a later commit.

* feat(tiktok): fetch top comments via ScrapeCreators when opted in

Mirrors the youtube_comments pattern: new env.is_tiktok_comments_available
gate (requires SCRAPECREATORS_API_KEY + tiktok_comments in INCLUDE_SOURCES),
tiktok.enrich_with_comments ranks posts and fetches via
GET /v1/tiktok/video/comments. Vote field is digg_count; text and user.nickname
come across verbatim. Pipeline calls the enricher right after TikTok search
when the gate is open.

Comment-fetch errors never crash the pipeline — the enricher returns an
empty list on 4xx/5xx.

* feat(normalize): pass TikTok top_comments through with digg_count->score mapping

Instagram uses the same shortform normalizer and has no comment fetcher
today, so the key is harmlessly absent there — no Instagram regression.

* feat(signals): add YouTube + TikTok top-comment score to engagement formula

Mirrors Reddit's 10% top-comment slot. Without top_comments present, the
formula reduces to views-dominant weighting; with a high-signal comment,
the item gets a meaningful bump (log1p(10k) ~ 9.2, weighted 0.10 = ~0.92
on the engagement score).

Updated the existing dominant-weight and missing-fields tests to the new
weights (0.45/0.32/0.13 for YT, 0.45/0.27/0.18 for TT). Views still dominate.

* feat(render): source-aware thresholds and vote labels for top comments

10 upvotes on Reddit signals community interest; 10 likes on a viral
TikTok is noise. Introduce per-source minimums (reddit 10, youtube 50,
tiktok 500) and native vote labels ('upvotes' for Reddit, 'likes' for
YT/TT). First-pass numbers — tune after live observation.

* docs: generalize top-comment quoting to YouTube + TikTok, add tiktok_comments opt-in

Synthesis instructions previously called out Reddit top comments only.
Now cover Reddit/YouTube/TikTok uniformly with source-appropriate vote
labels (upvotes vs likes), and explicitly frame YT transcript highlights
and comments as complementary signals. README and setup-wizard copy
document the new tiktok_comments INCLUDE_SOURCES token.

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-15 08:26:06 -04:00
Matt Van Horn 12167ee19e feat(skill): tune description and argument-hint for Claude skill-selector quality
- description leads with imperative 'Research' + 'what people actually say' (strong trigger signal for community/social-research prompts)
- argument-hint shows 3 concrete user phrasings instead of marketing copy
- 176 chars, well under Anthropic's 200-char cap
- preserves all source coverage (Reddit, X, YouTube, TikTok, Hacker News, Polymarket, GitHub, web)

Per ecosystem research (April 2026), trigger description quality is the single
biggest lever separating 500-install skills from 350k-install skills.
2026-04-14 17:42:54 -04:00
Matt Van Horn beb54e9e9d fix: sync version references in SKILL.md body and sync.sh cache path 2026-04-14 12:22:51 -04:00
Matt Van Horn 8d8ca68781 chore: bump version to 3.0.1 + changelog entry
Atomic bump across all four manifests:
- SKILL.md (root)
- skills/last30days/SKILL.md (internal spec)
- .claude-plugin/plugin.json
- gemini-extension.json

CHANGELOG entry documents the skill-upload packaging fix, vendor/ removal,
legacy plans/ removal, and the new scripts/build-skill.sh builder.
2026-04-14 12:21:24 -04:00
Matt Van Horn 0949b870e0 fix(skill): trim description to 167 chars (was 228, Anthropic caps at 200) 2026-04-14 12:20:20 -04:00
shalomma 8b67378964 Bump SKILL.md version header from v2.9.5 to v3.0.0
The SKILL.md prompt header still said v2.9.5 while pyproject.toml
and the rest of the codebase are on v3.0.0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:31:43 +03:00
Matt Van Horn 80892d31c6 Merge pull request #187 from pejmanjohn/contrib/mvanhorn-last30days-skill-100-fix-nux-argument-hint
fix: update argument-hint in root SKILL.md from last30days-3 to last30days
2026-04-09 21:16:59 -07:00
Pejman Pour-Moezzi a41bf5d8e7 fix: update argument-hint in root SKILL.md from last30days-3 to last30days 2026-04-09 12:12:16 -07:00
Matt Van Horn 0e5faa7a82 Merge pull request #175 from ziperlee/codex/readme-v3-alignment
docs: align README with v3 runtime
2026-04-09 06:25:00 -07:00
zipee bcc4694fa9 docs: point skill metadata at public repo 2026-04-09 08:40:07 +08:00
Pejman Pour-Moezzi 57ec92c299 last30days: require Python 3.12 in setup flows 2026-04-08 14:40:19 -07:00
Matt Van Horn 565deb443e fix: rename plugin from last30days-3 to last30days 2026-04-08 11:12:06 -07:00
Matt Van Horn 0a9ff16dfc feat: v3.0.0 - intelligent search, GitHub person/project mode, ELI5, 13+ sources
v3 rewrites the search engine from the ground up:

- Intelligent pre-research: resolves X handles, GitHub repos, subreddits,
  TikTok hashtags, and YouTube channels before searching
- GitHub person-mode: PR velocity, top repos by stars, release notes
- GitHub project-mode: live star counts, README, releases, top issues
- ELI5 mode: plain language synthesis, no jargon
- 13+ sources: Reddit, X, YouTube, TikTok, Instagram, HN, Polymarket,
  GitHub, Threads, Pinterest, Perplexity, Bluesky, Web
- Free Reddit comments via public JSON (no API key needed)
- Fun judge v2: humor scoring baked into narrative
- Cookie consent before browser scanning
- 10,000 free ScrapeCreators calls
- 1,012 tests

Thank you to the community contributors whose issues and PRs shaped v3:
@uppinote20 (#143), @zerone0x (#134, #136), @thinkun (#116),
@thomasmktong (#124), @fanispoulinakisai-boop (#100), @pejmanjohn (#78),
@zl190 (#115), @hnshah (#84, #85, #86)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 10:52:23 -07:00
Matt Van Horn 61904b31e3 feat: INCLUDE_SOURCES config + TikTok/Instagram opt-in in NUX
* feat: INCLUDE_SOURCES config + TikTok/Instagram opt-in in NUX

- INCLUDE_SOURCES=tiktok,instagram in .env forces sources on for all
  query types, bypassing the tier system
- NUX shows opt-in modal after ScrapeCreators key is saved: "Also
  search TikTok and Instagram?" with honest call-usage warning
- Tier system preserved as default — override only when INCLUDE_SOURCES set

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: neutral call-usage copy — works for free and paid tiers

---------

Co-authored-by: Matt Van Horn <mvanhorn@MacBook-Pro.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 06:22:37 -07:00
Matt Van Horn bb79d54b2b Revert "fix: ScrapeCreators modal sells all 5 platforms, not just Reddit"
This reverts commit 2eb9cd6fba.
2026-03-29 18:17:25 -07:00
Matt Van Horn 2eb9cd6fba fix: ScrapeCreators modal sells all 5 platforms, not just Reddit 2026-03-29 18:16:58 -07:00
Matt Van Horn 775596ce21 feat: v2.9.6 — free-first NUX, cookie extraction, quality scoring
Setup wizard with consent-first cookie extraction (Chrome/Firefox/Safari),
yt-dlp auto-install, ScrapeCreators push, quality scoring (5 core sources),
status banner redesign, honest Reddit labeling, inline YouTube transcripts,
Exa free web search, Reddit public fallback, and post-research quality nudge.

Co-authored-by: Matt Van Horn <mvanhorn@MacBook-Pro.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 14:33:17 -07:00
Matt Van Horn 4d6224f79a feat(youtube): extract transcript highlights like Reddit comment gems
Add extract_transcript_highlights() that scores sentences by specificity
(numbers, proper nouns, topic relevance) and filters YouTube filler
(subscribe, welcome back, etc). Top 5 highlights shown as structured
bullets in compact output. Full transcript moved to collapsible <details>
block so the LLM reads highlights first, full text on demand.

SKILL.md updated to instruct the judge agent to quote highlights
directly in synthesis, same as Reddit top comments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:49:38 -07:00
Matt Van Horn 7ffa508bb4 feat(last30days): improve ClawHub discoverability - description, tags
Updated frontmatter description to be more search-friendly for ClawHub.
Added 12 new tags: deep-research, twitter, bluesky, recency, news,
citations, multi-source, social-media, analysis, web-search, ai-skill,
clawhub. Also added 11 GitHub repo topics.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:27:53 -07:00
Matt Van Horn c2e18dbbeb fix(skill): use full /last30days name in comparison follow-up suggestions
The short alias /last30 only works on some platforms. Claude Code requires
the full /last30days name, so the follow-up suggestions after comparison
research were producing "Unknown skill: last30" errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 07:55:17 -07:00
Matt Van Horn b38703e53d feat(truthsocial): Add Truth Social as opt-in source
Mastodon-compatible API at truthsocial.com/api/v2/search.
Opt-in via TRUTHSOCIAL_TOKEN env var (bearer token from browser).
Silent when unconfigured. Full pipeline: search, parse, normalize,
score, dedupe, render across all 10 pipeline files.

27 new tests, 440 total passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 00:14:39 -07:00
Matt Van Horn adb5a672d9 fix(bluesky): make Bluesky opt-in with app password auth
searchPosts endpoint now returns 403 for unauthenticated requests.
Add session auth via createSession, gate on BSKY_HANDLE + BSKY_APP_PASSWORD
env vars. When unconfigured, Bluesky is completely invisible (no error).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 23:27:39 -07:00
Matt Van Horn ecf90c0281 feat(skill): add comparative mode and Bluesky references to SKILL.md
Add COMPARISON query type for "X vs Y" research with 3 parallel passes.
Add Bluesky stats line and update all source list references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 22:58:21 -07:00
Matt Van Horn 25e27bdade fix(skill): unquote $ARGUMENTS and add marketplace plugin path
- Remove double quotes around $ARGUMENTS so argparse can parse flags
  like --deep, --store separately instead of as part of the topic string.
  Fixes #61.

- Add ~/.claude/plugins/marketplaces/last30days-skill to the path
  discovery loop so marketplace installs can find scripts/.
  Fixes #54.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 21:55:24 -07:00
Matt Van Horn 2f16ff1ee8 feat(gemini): add Gemini CLI extension support
Add gemini-extension.json manifest with correct array-format settings,
symlink skills/last30days/SKILL.md to root SKILL.md for Gemini skill
discovery, add Gemini install paths to bash for-loop in both main and
open variant, and add Gemini CLI install instructions to README.

Incorporates the good parts of PR #53 (manifest, paths, README) while
avoiding duplicate SKILL.md, tool name scattering, and allowed-tools
pollution that would have created maintenance issues.

Closes #45

Co-Authored-By: Alex Ferrari <alex@thealexferrari.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 12:07:55 -07:00
Matt Van Horn 8f7fb5a7fe fix(release): v2.9.5 - remove re-introduced Save Research section
PR merges on March 7 (PR #48 Xiaohongshu, upstream merge) regressed
SKILL.md by re-introducing the "Save Research to Documents" section
that v2.9.4 removed. Those branches were forked before v2.9.4 and
brought the old content back via merge resolution.

Fixes: remove save section, restore --save-dir flag on bash command,
update agent mode line, add tool-call guard to STOP instruction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 11:55:35 -07:00
Matt Van Horn 28dff6e7b2 Merge remote-tracking branch 'upstream/main' 2026-03-07 16:36:15 -08:00
Matt Van Horn fad26d41fd fix: improve ClawHub security scan result
- Remove prompt-injection false positive ("you are now" → "treat yourself as")
- Declare AUTH_TOKEN and CT0 in frontmatter optionalEnv
- Clarify X token access language (no browser session access)
- Add permissions overview block near top of file

Zero functionality changes — metadata and prose only.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 18:35:38 -08:00
Matt Van Horn ef1f380cda feat: publish to ClawHub as last30days-official
- Add ClawHub badge and install command to README
- Update SKILL.md: metadata.openclaw canonical key, license/author/repository fields, optionalEnv vars, added instagram/polymarket tags
- Add .clawhubignore to exclude binary assets and dev files from bundle

Published: https://clawhub.ai/skills/last30days-official

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 18:08:14 -08:00
Matt Van Horn 6d5acb9121 feat(release): v2.9.4 - move save into Python script, zero post-invitation noise
Add --save-dir flag to last30days.py that saves raw research output
during the existing script run. Remove entire "Save Research to
Documents" section from SKILL.md (~45 lines). No more extra tool
calls, no (No output), no multi-minute cogitation after invitation.

Tested: --mock confirms file creation and duplicate date suffixing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 16:27:53 -08:00
Matt Van Horn 28d223e43c fix(release): v2.9.3 - foreground save, fix hallucinated user messages
CRITICAL: run_in_background callbacks caused model to re-engage after
save, hallucinate fake "Human:" messages, and generate unsolicited
multi-paragraph responses. Switch to foreground cat > heredoc which
executes sub-second with no callback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:50:17 -08:00
Matt Van Horn 471badd329 fix(release): v2.9.2 - silent save, no follow-up text after background save
- Background Bash heredoc instead of Write tool
- Suppress response text on save completion
- 📎 footer line replaces verbose confirmation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:41:55 -08:00
Matt Van Horn 18f6273f7c fix: save research silently via background Bash, not Write tool
The Write tool displays "Wrote N lines..." after the invitation,
ruining the end-of-run experience. Now saves via background Bash
with a subtle 📎 footer line in the invitation text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:34:22 -08:00
Matt Van Horn 9950d01ab4 fix: save research silently via background Bash, not Write tool
The Write tool displays "Wrote N lines..." after the invitation,
ruining the end-of-run experience. Now saves via background Bash
with a subtle 📎 footer line in the invitation text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:34:11 -08:00
Matt Van Horn cc774d5e69 feat(release): v2.9.1 - auto-save research to ~/Documents/Last30Days/
Sync from public repo. Every run now saves the complete briefing as a
topic-named .md file to ~/Documents/Last30Days/. Credit @devin_explores.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:50:43 -08:00
Matt Van Horn 49d993b162 feat(release): v2.9.1 - auto-save research to ~/Documents/Last30Days/
Bump version to 2.9.1, update changelog and release notes.
Credit @devin_explores for inspiring the feature.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:15:42 -08:00
Matt Van Horn f6a1769e35 feat(skill): auto-save research results to ~/Documents/Last30Days/
Every run now automatically saves the complete briefing (synthesis,
stats, follow-up suggestions) as a topic-named .md file in the user's
Documents folder. Agent mode also saves. No Python script changes -
this is purely a SKILL.md instruction addition.

Inspired by @devin_explores manually saving results to build a
personal research library.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:06:27 -08:00
Matt Van Horn 4d35b53eab docs: v2.9.0 release — ScrapeCreators Reddit default, top comments, smart discovery
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:03:40 -08:00
Matt Van Horn 7048fe7b83 feat(reddit): elevate top comments, improve subreddit discovery, default to ScrapeCreators
Three improvements from beta testing:

1. Top comments: 10% scoring weight for comment quality, 💬 top comment
   rendered prominently in compact/full output, increased insight limits
2. Subreddit discovery: relevance-weighted scoring with topic word matching,
   utility sub penalties (UTILITY_SUBS blocklist), engagement bonus
3. Default method: SKILL.md primaryEnv → SCRAPECREATORS_API_KEY, web-only
   banner recommends SC first, security section updated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:29:18 -08:00
Matt Van Horn 09b09946c0 feat: replace OpenAI Reddit search with ScrapeCreators API
- New scripts/lib/reddit.py: multi-query expansion, global search,
  subreddit discovery, targeted subreddit search, comment enrichment
- 68 results in 17s vs ~15 results in 60-90s (OpenAI)
- Cost: ~$0.02/search vs $0.03-0.10 (15-50x cheaper)
- Real engagement data (score, comments, dates) from API
- No more 429 rate limits on comment enrichment
- Falls back to OpenAI if SCRAPECREATORS_API_KEY missing
- Registered as last30daysbeta for parallel local testing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:55:02 -08:00
Matt Van Horn db75f9e341 feat: v2.8 — Instagram Reels source + TikTok ScrapeCreators migration
Add Instagram Reels as the 8th research source via ScrapeCreators API.
One API key (SCRAPECREATORS_API_KEY) now covers both TikTok and Instagram.

- Add scripts/lib/instagram.py: keyword search, transcript extraction,
  relevance scoring, engagement metrics (views, likes, comments)
- Add InstagramItem to schema, normalization, scoring, dedup, rendering
- Add Instagram to orchestrator pipeline, watchlist, and UI spinners
- Update SKILL.md: stats template, citation priority, item format,
  URL-to-name extraction rules, anti-Sources instruction
- Update README and CHANGELOG for v2.8
- Fix: Instagram/TikTok not running in --search= web-only path
- Fix: web stats line showing full URLs instead of domain names
- Replace APIFY_API_TOKEN with SCRAPECREATORS_API_KEY throughout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 07:00:51 -08:00
Matt Van Horn 740dcc5789 docs: update README and SKILL.md for ScrapeCreators TikTok API
Replace all Apify references with ScrapeCreators. Key points:
- No subscription required (was $5/mo with Apify)
- 100 free credits, pay-as-you-go after
- SCRAPECREATORS_API_KEY replaces APIFY_API_TOKEN
- Backwards compatible: APIFY_API_TOKEN still works as fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 05:17:30 -08:00
Matt Van Horn 1d18bee1a2 fix(skill): forward CLI flags through $ARGUMENTS to Python script
Remove double quotes around $ARGUMENTS in SKILL.md so bash word-splits
the expansion, and change argparse topic from nargs="?" to nargs="*"
so multi-word topics still work. Also document --store, --include-web,
--diagnose, and --timeout flags in the Options section.

Closes #36

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 13:52:08 -08:00
Matt Van Horn b990aed40e feat: add --no-native-web flag to skip Parallel AI in Claude Code
When running in Claude Code, the assistant has a built-in WebSearch tool
that's free and higher quality than Parallel AI/Brave/OpenRouter. Adding
--no-native-web to the SKILL.md invocation defers web search to the
assistant, saving API credits. OpenClaw invocations don't pass this flag,
so they continue using native web backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 06:34:03 -08:00
Matt Van Horn 1db0b6054a feat(tiktok): add TikTok as 7th signal source via Apify
Add TikTok search, scoring, and rendering using the Apify platform
(clockworks/tiktok-scraper actor). Users bring their own APIFY_API_TOKEN
($5/month free credits, no CC required). The shared apify_client_wrapper
module is designed for reuse by future Facebook/Instagram sources.

- New modules: tiktok.py (search + caption extraction), apify_client_wrapper.py
- Schema: TikTokItem dataclass, shares field on Engagement, Report.tiktok
- Pipeline: normalize → filter → score → sort → dedupe → cross-link → render
- Scoring: 0.50*log1p(views) + 0.30*log1p(likes) + 0.20*log1p(comments)
- SKILL.md bumped to v2.7 with TikTok stats, citations, and security docs
- 26 unit tests covering relevance, normalize, score, dedupe, render, round-trip

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 06:08:19 -08:00
Matt Van Horn 82efa6100b fix(skill): use plain source names in Web stats line, not URLs
URLs in markdown links wrap badly in terminals (discovered after first
fix attempt). Change to plain names like "Newsweek, Sportskeeda, Medium"
on the Web: stats line. Update citation note to explain the reason.

Tested on Dor Brothers, Kanye West, Logan Paul - no trailing Sources:
block appeared in any of the three test runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:54:06 -08:00
Matt Van Horn a52ed30109 fix(skill): suppress trailing Sources: block from WebSearch tool mandate
The WebSearch tool has a system-level mandate to append a Sources:
section at the end of every response. SKILL.md's old "DO NOT output
Sources: list" instruction was too weak to override it.

Fix: redirect citations into the stats block's Web: line as inline
links. The WebSearch citation requirement is satisfied there; an
explicit note after the stats block tells the model not to append
a separate trailing section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 23:44:55 -08:00