-
Notifications
You must be signed in to change notification settings - Fork 4
Competitor Intelligence
A self-discovering, LLM-driven competitive-intelligence pipeline. Free signals + Sonnet curation, $0 incremental cost, configurable per brand. Replaces the v2.2.x "weekly Tavily dump + Sonnet synth" with breadth that rivals commercial CI platforms (Crayon/Klue/Kompyte).
| What | How often | Where it lands |
|---|---|---|
| Discovery (Tavily) | weekly, cached 30 days | competitor_state.json .last_discovery |
| 5 signal collectors per competitor | parallel per weekly run | competitor_state/events.jsonl |
severity:high alerts |
every 10 min via competitor-alert cron |
Telegram + reports/.../alerts.log
|
severity:med digest |
daily 17:00 via competitor-daily cron |
reports/.../daily-YYYY-MM-DD.md + Telegram |
| Strategic synthesis | Mon 10:00 via competitor-intel cron |
reports/.../YYYY-MM-DD_<brand>.md + Telegram |
All in scripts/lib/competitor/. Bash + jq + curl, no external deps.
| Collector | Source | Severity heuristic |
|---|---|---|
reddit-search.sh |
Reddit JSON API (no auth) | score>100 + comments>20 = high; score>20 or complaint/vs/alternative keywords = med |
hn-search.sh |
HN Algolia API (no auth) | points>100 + comments>30 = high; Show HN / Launch HN / is hiring = med |
appstore-lookup.sh |
iTunes Lookup API (no auth) | version released within last 7d = high; >10k ratings = med |
jobs-feed.sh |
Greenhouse + Lever public APIs | VP/Head/Director/Chief/Founding = high; new geo or new team = med |
page-diff.sh |
curl + normalize + SHA-256 + diff | pricing page change with money token ($/€//mo) = high; other pricing/features/changelog = med |
page-diff.sh retains 12 snapshots per URL kind per competitor. State at competitor_state/<brand>/<comp>/snapshots/<kind>.<sha8>.txt with <kind>.latest symlink.
event-router.sh reads JSONL events on stdin and:
- Appends every event to
competitor_state/events.jsonl(append-only audit log). - Branches by
.severity:-
high→ also writes toqueue/immediate.jsonl— drained every 10 min byops-competitor-alert.sh. Produces🔥 [HIGH] {brand} {competitor} {kind}: {snippet}alerts. Telegram push +alerts.log. -
med→queue/daily.jsonl— drained at 17:00 (timezone-aware) byops-cron-competitor-daily.sh. Groups by competitor, top 3–5 snippets per competitor, single Telegram message ≤4000 chars. -
low→ no queue entry. Surfaces in weekly strategic synthesis only.
-
ops-cron-competitor-intel.sh fires Mon 10:00 in the configured timezone. Pipeline:
-
Discovery — Tavily, only if cached
last_discovery > 30 daysago. Cuts ~60% of Tavily spend. -
Per-competitor signal collection — all 5 collectors run in parallel background jobs per known competitor with 30-second timeout guards. Page-diff URLs are read from
preferences.json .competitor_intel.urls.<competitor>. - Brand mentions — Tavily news 7-day window for own brand → router.
-
Read 7-day event window from
events.jsonl(jq epoch filter). -
LLM synthesis —
claude_invokeSonnet 4.6 against the event log (cap 100k chars). Three-strategy JSON extraction (fenced block → bare regex → bullet-list scrape). Raw synthesis ALWAYS persisted toreports/competitor-intel/YYYY-MM-DD_<brand>-synthesis.mdbefore extraction so partial output is never lost. -
Update state — extracted competitor list (deduped, capped at
max_competitors) +last_run. -
Disk report — polished digest to
reports/competitor-intel/YYYY-MM-DD_<brand>.md+latest-<brand>.mdsymlink. Telegram push if creds present (additive only).
Output sections: NEW entrants, Competitor moves this week, Brand signal, Threats & opportunities.
The shared lib scripts/lib/competitor/context.sh exposes four functions, all jq-only and cheap to call:
| Function | Returns |
|---|---|
competitor_context [--brand X] [--window-days N] [--severity S] |
Aggregated JSON: brands, per-brand state + latest report path, events grouped by severity, queue sizes |
competitor_briefing_line |
One-line summary for briefings (Healify: 2 alerts · 5 med deltas · last run …) |
competitor_priority_items --top N |
Bullet list of top-N high-severity events for priority advisors |
competitor_vertical_slice <role> |
Role-filtered slice. Roles: marketing, ecom, ceo, cfo, coo, cto
|
| Surface | What you see |
|---|---|
/ops:go |
COMPETITOR row: alerts count, last_run, top-3 event snippets. Mobile: comp: N alerts (top: …)
|
/ops:next |
Priority 2 (between fires + comms): REACT: <competitor> <source> changed — see latest-<brand>.md
|
/ops:marketing |
PRICING MOVES + FUNDING/NEWS + SENTIMENT sections |
/ops:ecom |
APP RELEASES + PRODUCT/PRICING CHANGES sections |
/ops:yolo CEO/CTO/CFO/COO |
Each agent loads its role-specific vertical slice and folds it into their analysis |
Skills Reference#opscompetitors /ops:competitors
|
Dedicated dashboard + drill-down + add-url + alerts + refresh
|
bin/ops-competitors |
Standalone CLI — runnable outside Claude Code |
All consumers skip silently when competitor-intel is unconfigured. Mobile-mode compressed throughout (Rule 7).
In preferences.json:
{
"competitor_intel": {
"brand_name": "Healify",
"category": "AI health coaching apps",
"max_competitors": 5,
"report_timezone": "Europe/Amsterdam",
"app_store": true,
"urls": {
"Noom": {
"pricing": "https://www.noom.com/plans/",
"features": "https://www.noom.com/how-it-works/",
"careers": "https://www.noom.com/careers/"
}
}
}
}-
TAVILY_API_KEY— free tier 1000 searches/month covers ~30 brands. Get one at https://tavily.com.
-
TELEGRAM_BOT_TOKEN+TELEGRAM_CHAT_ID— for push delivery. Without these, reports persist to disk only.
Three cron entries in daemon-services.json (auto-added by /ops:setup):
{
"competitor-intel": { "enabled": true, "cron": "0 10 * * 1" },
"competitor-alert": { "enabled": true, "cron": "*/10 * * * *" },
"competitor-daily": { "enabled": true, "cron": "0 17 * * *" }
}$DATA_DIR/ (~/.claude/plugins/data/ops-ops-marketplace)
├── competitor_state.json # per-brand competitors + last_run + last_discovery
├── competitor_state/
│ ├── events.jsonl # append-only audit log of all signal events
│ ├── queue/
│ │ ├── immediate.jsonl # severity:high, drained every 10 min
│ │ ├── daily.jsonl # severity:med, drained 17:00
│ │ └── immediate.processed.jsonl # archive of processed alerts
│ └── <brand-slug>/<competitor-slug>/snapshots/
│ ├── pricing.<sha8>.txt # page-diff snapshots
│ └── pricing.latest # → symlink to current
└── reports/competitor-intel/
├── YYYY-MM-DD_<brand>.md # weekly digest
├── YYYY-MM-DD_<brand>-synthesis.md # raw LLM synthesis (preserved before extraction)
├── latest-<brand>.md # → symlink to latest weekly
├── daily-YYYY-MM-DD.md # daily med-severity roll-up
└── alerts.log # every high-severity alert (rolling)
At 10 configured brands:
- Tavily: ~13 calls/wk total (discovery cached 30 days; per-competitor news only fires when no other signal landed that week)
- Sonnet: ~320k tokens/month total against Max-OAuth (no API billing)
- Embedding (if v2.4 adds dedup): local
all-MiniLM-L6-v2— free, or OpenAI text-embedding-3-small at ~$0.02/wk - HTTP scraping: $0
Total $0 incremental at portfolio scale.
/ops:competitors # dashboard — all brands
/ops:competitors Healify # drill-down — 30d timeline for one brand
/ops:competitors refresh # manually trigger weekly cron now
/ops:competitors refresh Healify # refresh a specific brand
/ops:competitors add-url Healify Noom pricing https://www.noom.com/plans/
/ops:competitors alerts # tail last 20 of alerts.logOr via the standalone CLI:
ops-competitors # same subcommands as the skill- Embedding-based dedup of news items (collapse 5 versions of same story → 1)
- Live Notion DB sync (per-competitor pages auto-updated)
- Self-improving feedback loop (Telegram 👍/👎 reactions → signal weight tuning)
- Auto-discovery of new signal sources from LLM proposals
- Multi-brand portfolio dashboard view
- G2 official API — paywalled, not worth it at this scale
- SimilarWeb traffic data — paywalled
- Crunchbase API — $$$
- Anything that requires keeping a vendor in the loop
Free signals + LLM curation beats their value at small/medium portfolio scale.
Source: scripts/lib/competitor/ (collectors + router + context lib), scripts/ops-cron-competitor-intel.sh (weekly), scripts/ops-competitor-alert.sh (immediate), scripts/ops-cron-competitor-daily.sh (daily), bin/ops-competitors (CLI), skills/ops-competitors/SKILL.md (skill).
Changelog: shipped in v2.3.0 (producer) + v2.3.1 (consumers) + v2.3.2 (docs). See Changelog for full history.