Skip to content

hoanghieu512/InkPilot

Repository files navigation

InkPilot

CΓ΄ng cα»₯ CLI local-first phα»₯c vα»₯ nghiΓͺn cα»©u nα»™i dung crypto β€” scrape RSS tα»« nhiều nguα»“n, AI scoring bαΊ±ng Claude Haiku (0–10), research brief bαΊ±ng Claude Sonnet, lΖ°u vΓ o SQLite, hiển thα»‹ tiered inbox (HOT / OTHER). Người dΓΉng tα»± viαΊΏt bΓ i rα»“i Δ‘Δƒng lΓͺn X (Twitter). ĐÒy KHΓ”NG phαΊ£i bot tα»± Δ‘α»™ng β€” mọi post đều do người viαΊΏt vΓ  duyệt.


Overview

TypeScript + Node.js, scrape RSS song song tα»« 16 nguα»“n (9 enabled), dedup theo URL, score bαΊ±ng Claude Haiku (batch 10 bΓ i/call), generate research brief bαΊ±ng Claude Sonnet (per article), lΖ°u vΓ o SQLite (better-sqlite3). Mα»—i bΓ i viαΊΏt được theo dΓ΅i qua state machine (new β†’ read β†’ starred β†’ drafted β†’ posted β†’ dismissed). BΓ i score < 6 tα»± Δ‘α»™ng dismissed.

CαΊ₯u hΓ¬nh credentials qua .env; nguα»“n RSS chỉnh trong src/config/rss-sources.ts.

Chi tiαΊΏt kiαΊΏn trΓΊc, luα»“ng dα»― liệu vΓ  module: xem PROJECT_OVERVIEW.md.


Features

  • RSS scraper β€” scrape 6 nguα»“n song song (Promise.allSettled), dedup theo URL (INSERT OR IGNORE), timeout 10 giΓ’y/feed.
  • AI scoring (Haiku) β€” batch scoring 10 bΓ i/call, Δ‘iểm 0–10 (decimal, e.g. 7.2, 8.5) + 12 category cα»‘ Δ‘α»‹nh (L2, DeFi, AI x Crypto, Developer Tooling, SocialFi, Bitcoin, Regulation, Macro, Research/Protocol, Price/Trading, Exchange/Corporate, Other) + reasoning + suggested angle; cost tracking (token + USD).
  • Tiered inbox β€” HOT (score 7.5+) hiện mαΊ·c Δ‘α»‹nh vα»›i suggested angle, OTHER (6–7.4), Dismissed (< 6) tα»± αΊ©n. Recency filter 30 ngΓ y mαΊ·c Δ‘α»‹nh, --days=N để override.
  • Research brief (Sonnet) β€” npm run brief <id> generate brief cho bαΊ₯t kα»³ article: WHY IT MATTERS + related stories + suggested angles (VN primary + EN). Hook-first angle prompts (khΓ΄ng tΓ³m tαΊ―t lαΊ‘i tin). Cache trong DB β€” lαΊ§n 2 khΓ΄ng gọi API; npm run brief -- <id> --refresh để gọi lαΊ‘i Sonnet vΓ  ghi Δ‘Γ¨ cache.
  • Angle markdown (Obsidian) β€” mα»—i lαΊ§n brief xong tα»± ghi file .md vΓ o ~/Dev/vault/projects/content-creator/angles/ tα»« template ~/Dev/vault/templates/angle-template.md (placeholder __KEY__ β€” tΖ°Ζ‘ng thΓ­ch obsidian/YAML, khΓ΄ng dΓΉng {{}}). Terminal hiện πŸ’Ύ Saved: ~/.... ThiαΊΏu template β†’ chỉ cαΊ£nh bΓ‘o, brief vαΊ«n hiện.
  • User context β€” brief cΓ‘ nhΓ’n hΓ³a dα»±a trΓͺn about-me.md + tone-guidelines.md đọc tα»« ~/Dev/projects/Content-Creator/; khΓ΄ng cΓ³ thΓ¬ vαΊ«n chαΊ‘y.
  • OG image β€” tα»± lαΊ₯y og:image tα»« trang gα»‘c, 5 request song song, timeout 5 giΓ’y; khΓ΄ng bao giờ crash.
  • Article state machine β€” new β†’ read β†’ starred β†’ drafted β†’ posted β†’ dismissed.
  • Source upsert β€” seedSources() dΓΉng ON CONFLICT DO UPDATE β€” thay Δ‘α»•i URL hoαΊ·c enabled/disabled trong config tα»± sync vΓ o DB.
  • Graceful degradation β€” lα»—i 1 feed hoαΊ·c Haiku/Sonnet API failure khΓ΄ng crash toΓ n bα»™.
  • Source status β€” npm run sources:status in bαΊ£ng per-source: enabled/disabled, sα»‘ bΓ i, ngΓ y bΓ i gαΊ§n nhαΊ₯t, lαΊ§n fetch cuα»‘i; khΓ΄ng cαΊ§n Anthropic API key.
  • Verbose fetch β€” npm run fetch -- --verbose log per-feed: sα»‘ item feed trαΊ£ về, new vs duplicate sau mα»—i nguα»“n.
  • Scoring diagnostic β€” npm run stats:scoring [--days=N] in histogram 8 bucket (chia tαΊ‘i 7.5) + tỉ lệ HOT/OTHER/dismissed + breakdown theo Haiku category; khΓ΄ng cαΊ§n API key.
  • Per-source diagnostic β€” npm run stats:sources [--days=N] in bαΊ£ng per-source: total scored, avg score, HOT/OTHER/dismissed counts, HOT%; khΓ΄ng cαΊ§n API key.
  • Near-HOT inspector β€” npm run inspect:near-hot [--limit=N] [--days=N] hiện 10 bΓ i score 7–7.4 vα»›i full Haiku reasoning vΓ  suggested angle; dΓΉng để diagnose threshold (hiện tαΊ‘i: 7.5).
  • Reply tracking (X analytics) β€” npm run reply:analyze đọc 2 file CSV X Analytics, phΓ’n loαΊ‘i reply KOL vs original (reply = text bαΊ―t Δ‘αΊ§u @), tra niche tα»«ng KOL (security/tokenomics/l1l2/other), enrich qua TwitterAPI.io (giờ reply + imp/eng tweet gα»‘c), tΓ­ch lΕ©y vΓ o bαΊ£ng reply_tracking (idempotent theo Post id), ghi snapshot JSON ra vault cho dashboard Newsroom. --skip-enrich chαΊ‘y CSV-only (khΓ΄ng tα»‘n API); --content=/--overview= override path.
  • 71 tests β€” Vitest, in-memory SQLite; bao gα»“m dedup, seeding, states, mocked Anthropic (cαΊ£ Haiku vΓ  Sonnet), fallback scoring, brief cache, vΓ  reply tracking (CSV parser, niche lookup, DB idempotency, snapshot builder, orchestrator).

Tech stack

Lα»›p CΓ΄ng nghệ
Runtime Node.js 20+, TypeScript 5.7, tsx
Database SQLite via better-sqlite3 (sync API)
AI β€” Filter Anthropic SDK β€” Claude Haiku (claude-haiku-4-5-20251001): batch relevance scoring
AI β€” Brief Anthropic SDK β€” Claude Sonnet (claude-sonnet-5): research brief generation
Reply enrichment TwitterAPI.io via native fetch (TWITTERAPI_IO_KEY) β€” parent-tweet metrics + reply hour
RSS rss-parser
Config dotenv + .env; AI_MODELS (haiku / sonnet) trong src/config/index.ts β€” Δ‘α»•i model mα»™t chα»— cho toΓ n app
Test Vitest
Publishing (planned) X (Twitter) API

CΓ‘ch chαΊ‘y (How to run)

YΓͺu cαΊ§u

CΓ i Δ‘αΊ·t

cd InkPilot
npm install

cp .env.example .env
# Sα»­a .env: Δ‘iền ANTHROPIC_API_KEY

Sα»­ dα»₯ng

Fetch + Score bΓ i viαΊΏt

Lệnh MΓ΄ tαΊ£
npm run fetch Scrape RSS β†’ dedup β†’ insert β†’ OG image β†’ Haiku scoring
npm run fetch -- --verbose NhΖ° trΓͺn + log per-feed: sα»‘ item, new vs duplicate
npm run fetch
# Output:
# Fetch complete:
#   Sources checked: 6
#   New articles:    14
#   Duplicates:      823
#   Scored:          14 (HOT: 3, OTHER: 7, Dismissed: 4)
#   Cost:            $0.0031 (Haiku: 3.2K in, 1.4K out tokens)

npm run fetch -- --verbose
# ThΓͺm per-feed log:
#   Decrypt: 25 items β†’ 3 new, 22 duplicates
#   Bankless: 18 items β†’ 2 new, 16 duplicates
#   ...

Xem bΓ i viαΊΏt (Tiered Inbox)

# MαΊ·c Δ‘α»‹nh: hiện HOT trΖ°α»›c, sau Δ‘Γ³ OTHER (last 30 days)
npm run list

# Chỉ HOT (score 7.5+) β€” cΓ³ suggested angle
npm run list -- --hot

# Chỉ OTHER (score 6–7.4)
npm run list -- --other

# TαΊ₯t cαΊ£ (bao gα»“m dismissed)
npm run list -- --all

# Recency filter
npm run list -- --hot --days=7        # chỉ 7 ngΓ y gαΊ§n nhαΊ₯t
npm run list -- --all --days=90       # mở rα»™ng ra 3 thΓ‘ng

# Kết hợp filter
npm run list -- --hot --today --limit=10
npm run list -- --source=vitalik --limit=5
npm run list -- --state=new --today

Output mαΊ·c Δ‘α»‹nh (tiered):

HOT  πŸ”₯ (score 7.5+)
──────────────────────────────────────────────────────────────────────────────────────────
[9.1]   42  Base introduces new fee mechanism for...   Base Blog        2h ago
            β†’ Compare with Arbitrum's approach and developer adoption impact
[8.5]   38  EigenLayer restaking hits $10B TVL amid..  The Block        5h ago
            β†’ What restaking saturation means for ETH staking yields

OTHER  (score 6–7.4)
──────────────────────────────────────────────────────────────────────────────────────────
[7.2]   41  DeFi TVL reaches new high amid...          CoinDesk         3h ago
[6.8]   39  Kraken acquires...                         CoinDesk         6h ago

Showing 2 of 139 hot, 2 of 423 other (last 30 days). Use --days=N or --limit=N to adjust.

Research Brief

# Generate brief cho article #42
npm run brief 42

# Bỏ qua cache + regenerate Sonnet + ghi Δ‘Γ¨ file angle
npm run brief -- 42 --refresh

One-time β€” vault template (Obsidian):

mkdir -p ~/Dev/vault/templates ~/Dev/vault/projects/content-creator/angles
cp templates/angle-template.md ~/Dev/vault/templates/angle-template.md

Output:

══════════════════════════════════════════════════════════════
BRIEF #42 β€” Base introduces new fee mechanism
Source: Base Blog  |  Score: 9.1  |  Published: 2 days ago
URL: https://base.mirror.xyz/...
══════════════════════════════════════════════════════════════

WHY IT MATTERS
Base's new fee mechanism decouples L2 transaction costs from L1 gas
spikes, affecting all apps deployed on Base (~2,500 contracts).

RELATED STORIES (last 7 days)
  [8.5]  #38  EigenLayer restaking hits $10B TVL  β€”  5 days ago
  [7.2]  #41  DeFi TVL reaches new high           β€”  3 days ago

SUGGESTED ANGLES

  πŸ‡»πŸ‡³  TiαΊΏng Việt
  1.  Fee mechanism mα»›i cα»§a Base β€” template cho cΓ‘c L2 khΓ‘c hay chỉ
      workaround cho vαΊ₯n đề gas cα»§a riΓͺng Base?
  2.  So sΓ‘nh cΓ‘ch Base handle fee vs Arbitrum Nitro β€” cΓΉng bΓ i toΓ‘n
      nhΖ°ng approach khΓ‘c nhau hoΓ n toΓ n.

  🌐  English
  1.  Base's fee redesign: structural advantage for app-specific L2s
      or a band-aid for Ethereum's gas problem?

══════════════════════════════════════════════════════════════
Cost: $0.01  |  Sonnet: 1.2K in / 0.4K out tokens

πŸ’Ύ  Saved: ~/Dev/vault/projects/content-creator/angles/2026-04-18-42-base-fee-mechanism.md
══════════════════════════════════════════════════════════════

LαΊ§n 2 chαΊ‘y cΓΉng article β†’ dΓΉng cache, khΓ΄ng gọi API (file angle vαΊ«n được ghi lαΊ‘i / overwrite cΓΉng tΓͺn):

══════════════════════════════════════════════════════════════
(cached β€” no API call)

πŸ’Ύ  Saved: ~/Dev/vault/projects/content-creator/angles/2026-04-18-42-base-fee-mechanism.md
══════════════════════════════════════════════════════════════

Scoring diagnostics

# Histogram phΓ’n bα»‘ score + HOT/OTHER/dismissed ratio (7 ngΓ y mαΊ·c Δ‘α»‹nh)
npm run stats:scoring
npm run stats:scoring -- --days=30

# Per-source: avg score, HOT count, HOT% (7 ngΓ y mαΊ·c Δ‘α»‹nh)
npm run stats:sources
npm run stats:sources -- --days=14

# 10 bΓ i score 7–7.9 kΓ¨m full Haiku reasoning (để kiểm tra threshold)
npm run inspect:near-hot
npm run inspect:near-hot -- --limit=20 --days=14

Reply tracking (X analytics)

PhΓ’n tΓ­ch reply KOL tα»« X Analytics CSV β†’ enrich β†’ snapshot JSON cho dashboard Newsroom.

One-time β€” credential: thΓͺm TWITTERAPI_IO_KEY vΓ o .env (lαΊ₯y key tαΊ‘i twitterapi.io).

Input: export 2 file CSV tα»« X Analytics vΓ o ~/Dev/vault/projects/content-creator/analytics/raw/:

  • content-latest.csv (per-post: Post id, Date, Post text, Impressions, Engagements, New follows…)
  • overview-latest.csv (per-day topline)
# Đọc CSV β†’ phΓ’n loαΊ‘i reply/original β†’ tra niche β†’ enrich (TwitterAPI.io) β†’ reply_tracking β†’ snapshot JSON
npm run reply:analyze

# CSV-only, khΓ΄ng gọi API (khΓ΄ng tα»‘n tiền)
npm run reply:analyze -- --skip-enrich

# Override đường dαΊ«n CSV
npm run reply:analyze -- --content=/path/to/content.csv --overview=/path/to/overview.csv

Output: in summary terminal (reply count, imp share, dud rate, top KOLs, by-niche) vΓ  ghi snapshot vΓ o ~/Dev/vault/projects/content-creator/analytics/reply-tracking/latest.json (schema cα»‘ Δ‘α»‹nh β€” Newsroom đọc file nΓ y).

  • Reply detection: post text bαΊ―t Δ‘αΊ§u bαΊ±ng @ β†’ reply; KOL = handle ngay sau @ Δ‘αΊ§u tiΓͺn.
  • Niche: tra tα»« src/config/kol-niches.ts (security/tokenomics/l1l2/other; khΓ΄ng cΓ³ trong list β†’ other). Sync tay tα»« vault kol-reply-list.md.
  • Dud: reply cΓ³ impressions < 50.
  • Idempotent: chαΊ‘y lαΊ‘i cΓΉng CSV khΓ΄ng nhΓ’n Δ‘Γ΄i row (key theo Post id); enrichment chỉ chαΊ‘y 1 lαΊ§n/row.
  • Graceful: thiαΊΏu TWITTERAPI_IO_KEY β†’ bΓ‘o lα»—i rΓ΅ (hoαΊ·c dΓΉng --skip-enrich); lα»—i enrich 1 reply β†’ skip + warn, khΓ΄ng crash; thiαΊΏu content CSV β†’ lα»—i rΓ΅; thiαΊΏu overview CSV β†’ period suy tα»« content.

Xem trαΊ‘ng thΓ‘i nguα»“n

npm run sources:status
# Output:
# Sources status:
#
#   Source                    Status    Articles  Last article    Last fetch
#   ──────────────────────────────────────────────────────────────────────
#   Bankless                  enabled    243 arts  3h ago          2h ago
#   CoinDesk                  enabled    512 arts  1h ago          1h ago
#   Decrypt                   enabled    389 arts  2h ago          2h ago
#   CoinCu News               enabled     87 arts  5h ago          4h ago
#   Ethereum Foundation Blog  enabled     34 arts  3d ago          2h ago
#   Vitalik's Blog            enabled     12 arts  14d ago         2h ago
#   The Block                 disabled     0 arts  β€”               β€”
#   Base Blog                 disabled     0 arts  β€”               β€”
#   ...

Test

npm test          # ChαΊ‘y 71 tests
npm run test:watch  # Watch mode

Project structure

src/
β”œβ”€β”€ config/
β”‚   β”œβ”€β”€ index.ts           # Load .env β†’ Config; AI_MODELS, SCORE_THRESHOLDS, REPLY_THRESHOLDS, requireTwitterApiIoKey
β”‚   β”œβ”€β”€ types.ts           # Config interface
β”‚   β”œβ”€β”€ rss-sources.ts     # Source of truth: 16 feeds (9 enabled) Γ— 4 tiers
β”‚   └── kol-niches.ts      # KOL handle β†’ niche map (lookupNiche); synced by hand from vault kol-reply-list.md
β”œβ”€β”€ content-filter/
β”‚   β”œβ”€β”€ index.ts           # filterNewArticles orchestrator (batch + state update)
β”‚   β”œβ”€β”€ haiku-filter.ts    # Anthropic SDK β€” scoreArticles (batch 10, cost tracking)
β”‚   └── types.ts           # ArticleToScore, FilterResult, BatchFilterResult
β”œβ”€β”€ research-briefer/
β”‚   β”œβ”€β”€ index.ts           # generateBrief orchestrator (load β†’ related β†’ Sonnet β†’ cache β†’ export angle)
β”‚   β”œβ”€β”€ sonnet-briefer.ts  # Anthropic SDK β€” generateBriefWithSonnet (cost tracking)
β”‚   β”œβ”€β”€ angle-exporter.ts # fill __KEY__ template β†’ vault/angles/*.md
β”‚   β”œβ”€β”€ formatter.ts       # printBrief β€” terminal output formatting
β”‚   └── types.ts           # Brief, RelatedArticle, SuggestedAngles
β”œβ”€β”€ database/
β”‚   β”œβ”€β”€ index.ts           # Singleton DB connection (WAL, foreign keys)
β”‚   β”œβ”€β”€ schema.ts          # CREATE TABLE Γ— 8 + indexes
β”‚   β”œβ”€β”€ migrations.ts      # Run schema + auto-migrate old tables
β”‚   β”œβ”€β”€ types.ts           # ArticleState, Source, Article, ArticleStateRow
β”‚   β”œβ”€β”€ sources.ts         # seedSources (upsert), getEnabledSources, getSourceBySlug
β”‚   β”œβ”€β”€ articles.ts        # insertArticle (dedup), getArticlesWithFilter
β”‚   β”œβ”€β”€ article-states.ts  # createArticleState, updateArticleState
β”‚   β”œβ”€β”€ filter-results.ts  # insertFilterResult, isArticleScored, cacheArticleBrief, getCachedBrief
β”‚   β”œβ”€β”€ posts.ts           # insertPost, getPostsByPlatform, countTodayPosts
β”‚   └── reply-tracking.ts  # upsertReply (idempotent), updateReplyEnrichment, getReplies* queries
β”œβ”€β”€ feed-fetcher/
β”‚   β”œβ”€β”€ index.ts           # runFetch orchestrator (parallel + OG + scoring)
β”‚   β”œβ”€β”€ rss-parser.ts      # fetchFeed β†’ FeedItem[]
β”‚   └── og-extractor.ts    # extractOgImageUrl β†’ string | null
β”œβ”€β”€ reply-tracking/
β”‚   β”œβ”€β”€ index.ts           # runReplyAnalyze orchestrator (parse β†’ upsert β†’ enrich β†’ snapshot)
β”‚   β”œβ”€β”€ csv-parser.ts      # parseCsv (RFC-4180), parseContentCsv/parseOverviewCsv, parseXDate, extractKolHandle, derivePeriod
β”‚   β”œβ”€β”€ snapshot-builder.ts # buildSnapshot (pure) β†’ Newsroom contract; weekStart, nowIsoPlus7
β”‚   β”œβ”€β”€ enricher.ts        # enrichReply (TwitterAPI.io); mapTweet, computeHourPlus7
β”‚   β”œβ”€β”€ exporter.ts        # exportSnapshot β†’ vault reply-tracking/latest.json
β”‚   └── types.ts           # ContentRow, OverviewRow, Period, ReplyEnrichment, ReplySnapshot
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ fetch.ts           # CLI: npm run fetch [--verbose]
β”‚   β”œβ”€β”€ list.ts            # CLI: npm run list (tiered inbox, --days=N)
β”‚   β”œβ”€β”€ brief.ts           # CLI: npm run brief <id> [--refresh]
β”‚   β”œβ”€β”€ sources-status.ts  # CLI: npm run sources:status (per-source health table)
β”‚   β”œβ”€β”€ stats-scoring.ts   # CLI: npm run stats:scoring [--days=N] (histogram + categories)
β”‚   β”œβ”€β”€ stats-sources.ts   # CLI: npm run stats:sources [--days=N] (per-source HOT rate)
β”‚   β”œβ”€β”€ inspect-near-hot.ts # CLI: npm run inspect:near-hot (score 7–7.4 + full reasoning)
β”‚   └── reply-analyze.ts   # CLI: npm run reply:analyze [--skip-enrich] [--content=] [--overview=]
└── utils/
    └── logger.ts          # Leveled, colored console logging
templates/
└── angle-template.md      # Copy to ~/Dev/vault/templates/angle-template.md
tests/
β”œβ”€β”€ database.test.ts       # 8 tests: schema, posts CRUD
β”œβ”€β”€ feed-fetcher.test.ts   # 14 tests: sources, articles, states, mocked fetch
β”œβ”€β”€ content-filter.test.ts # 10 tests: filter DB, scoring, mocked Anthropic, fallback
β”œβ”€β”€ research-briefer.test.ts # 7 tests: cache, related query, mocked Sonnet, fallback
└── reply-tracking.test.ts  # 32 tests: niche lookup, CSV parser, DB idempotency, snapshot builder, enricher, orchestrator

RSS Sources

Tier Nguα»“n LoαΊ‘i NgΓ΄n ngα»― TαΊ§n suαΊ₯t Status
1 Decrypt, Bankless, CoinDesk, Blockworks crypto / defi en 1h enabled
1 ETH Research Forum, Bitcoin Optech research-technical en 1h enabled
1 The Block crypto en 1h disabled β€” Cloudflare 403
2 Ethereum Foundation Blog, Arbitrum Foundation protocol / protocol-l2 en 1h enabled
2 Base Blog protocol en 1h disabled β€” Cloudflare JS challenge
2 Optimism Blog protocol-l2 en 1h disabled β€” feed stale since Jun 2025
2 Vitalik's Blog protocol en 1h disabled β€” kept for FK integrity (articles in DB)
3 CoinCu News vietnamese vi 2h enabled
3 Coin68, TαΊ‘p ChΓ­ Bitcoin vietnamese vi 2h disabled β€” kept for FK integrity
4 MarkTechPost ai en 2h disabled β€” kept for FK integrity

ThΓͺm/xΓ³a/sα»­a nguα»“n: sα»­a file src/config/rss-sources.ts β†’ thay Δ‘α»•i tα»± sync vΓ o DB lαΊ§n fetch tiαΊΏp.


AI Scoring

Haiku scoring dΓΉng hệ thα»‘ng prompt theo niche priority stack cα»§a creator:

Priority Niche VΓ­ dα»₯
PRIMARY (~50%) Security Hacks, exploits, bridge attacks, post-mortems, smart contract vulnerabilities, audit findings, phishing, bug bounties
SECONDARY (~30%) Tokenomics Token design, emission schedules, liquid/restaking (Lido, EigenLayer), protocol revenue, fee mechanisms, treasury, airdrop design
TERTIARY (~20%) L1/L2 Infra Ethereum upgrades + EIPs, L2 rollups, Bitcoin Optech/Lightning, DA layers, MEV/PBS
Score Ý nghΔ©a HΓ nh Δ‘α»™ng
9.0–10.0 Sα»± cα»‘ bαΊ£o mαΊ­t lα»›n cΓ³ phΓ’n tΓ­ch, nΓ’ng cαΊ₯p protocol landmark, thay Δ‘α»•i tokenomics tαΊ§m ecosystem HOT β€” hiện mαΊ·c Δ‘α»‹nh
7.5–8.9 PhΓ‘t triển rΓ΅ trong 3 niche β€” cΓ³ angle mαΊ‘nh để viαΊΏt take HOT β€” hiện mαΊ·c Δ‘α»‹nh
5.0–7.4 LiΓͺn quan nhαΊΉ, Γ­t tiềm nΔƒng angle OTHER β€” hiện khi --other
< 5.0 Spam, listicle, price prediction, tin ngoΓ i niche Auto-dismissed (< 6.0)

Penalty (score thαΊ₯p hΖ‘n): price analysis thuαΊ§n, celebrity endorsements, meme coins, exchange listings, airdrop farming guides, generic regulation, price predictions.

Chi phΓ­ thα»±c tαΊΏ: ~$0.50 cho 1000 bΓ i (Haiku pricing: $0.80/1M input, $4.00/1M output tokens).

Research Brief

Sonnet brief cho mα»—i article, cΓ‘ nhΓ’n hΓ³a theo voice/tone cα»§a user:

ThΓ nh phαΊ§n MΓ΄ tαΊ£
WHY IT MATTERS 2–3 cΓ’u giαΊ£i thΓ­ch Γ½ nghΔ©a, dΓΉng sα»‘ liệu cα»₯ thể
RELATED STORIES Tα»‘i Δ‘a 5 bΓ i liΓͺn quan (7 ngΓ y, score β‰₯ 6, cΓΉng category/keyword)
SUGGESTED ANGLES 2–3 gΓ³c VN + 1 gΓ³c EN tα»‘i Δ‘a; hook Δ‘αΊ§u dΓ²ng, 2–3 cΓ’u, khΓ΄ng tΓ³m tαΊ―t lαΊ‘i headline
Cache KαΊΏt quαΊ£ lΖ°u trong filter_results.ai_context β€” lαΊ§n 2 khΓ΄ng gọi Sonnet; --refresh để gọi lαΊ‘i
Angle file Markdown vΓ o ~/Dev/vault/projects/content-creator/angles/YYYY-MM-DD-<id>-<slug>.md (template __KEY__)

User context: đọc Δ‘α»™ng tα»« ~/Dev/projects/Content-Creator/about-me.md + tone-guidelines.md. KhΓ΄ng cΓ³ file thΓ¬ vαΊ«n chαΊ‘y (graceful fallback).

Chi phΓ­: ~$0.01/brief (Sonnet pricing: $3.00/1M input, $15.00/1M output tokens).


Roadmap

  • Slice 1 β€” First Cast (DB schema, posts CRUD, config, logger)
  • Slice 2 β€” First Fetch (RSS scrape β†’ dedup β†’ SQLite β†’ OG image β†’ CLI list)
  • Slice 3 β€” Smart Filter (Claude Haiku scoring β†’ tiered inbox, auto-dismiss, decimal scores, recency filter)
  • Slice 4 β€” Research Brief (Claude Sonnet brief β†’ WHY IT MATTERS + related stories + suggested angles, cache, user context)
  • v0.2.0 β€” Feed fixes (disable The Block + Base Blog, Cloudflare-blocked), npm run sources:status, --verbose flag
  • v0.3.0 β€” Source expansion (add Blockworks, ETH Research, Bitcoin Optech, Arbitrum, Optimism; remove 4 stale sources; new categories protocol-l2 + research-technical)
  • v0.3.1 β€” Data integrity fix (939 articles re-mapped after source_id orphan bug; disable stale Optimism feed; add repairArticleSourceIds)
  • v0.4.0 β€” HOT pipeline diagnostics (stats:scoring, stats:sources, inspect:near-hot)
  • v0.4.1 β€” HOT threshold 8.0 β†’ 7.5, fixed 12-category Haiku enum, recency filter bug fix
  • v0.4.2 β€” List footer shows "X of Y" total count when limit is hit; refactored list.ts condition builder
  • v0.4.3 β€” Haiku niche priority stack (Security > Tokenomics > L1/L2 Infra); fix process hang on fetch/brief completion
  • v0.5.0 β€” Reply Tracking: reply_tracking table + npm run reply:analyze (X Analytics CSV β†’ KOL niche β†’ TwitterAPI.io enrichment β†’ snapshot JSON for Newsroom); kol-niches.ts config; TWITTERAPI_IO_KEY
  • v0.5.1 β€” Fix reply:analyze scope + enrichment: summary/enrichment scoped to latest week, idempotent re-runs, QPS throttle + 429 backoff (TWITTERAPI_IO_QPS)
  • v0.5.2 β€” Brief model β†’ Claude Sonnet 5 (claude-sonnet-5); disable adaptive thinking + raise max_tokens 1000 β†’ 1300 for the new tokenizer
  • Slice 5 β€” X API Adapter (publish to Twitter)
  • Slice 6 β€” TUI / Ink (interactive terminal UI)
  • Future β€” realtime Reply Monitor (builds on the reply_tracking data layer)

Troubleshooting

Lα»—i GiαΊ£i phΓ‘p
Missing required env var: ANTHROPIC_API_KEY Điền ANTHROPIC_API_KEY trong .env
Haiku/Sonnet API error / rate limit Scoring bỏ qua β€” bΓ i giα»― state new; brief trαΊ£ partial result
The Block / Base Blog khΓ΄ng fetch được Đã disabled do Cloudflare block β€” xem npm run sources:status
Feed timeout / 4xx errors BΓ¬nh thường β€” feed lα»—i được bỏ qua, cΓ‘c nguα»“n khΓ‘c vαΊ«n chαΊ‘y
No scored articles found ChαΊ‘y npm run fetch trΖ°α»›c; dΓΉng --all để xem tαΊ₯t cαΊ£ kể cαΊ£ chΖ°a score
Article #X not found Kiểm tra ID bαΊ±ng npm run list -- --all; cΓ³ thể article khΓ΄ng tα»“n tαΊ‘i
Article #X has not been scored yet ChαΊ‘y npm run fetch để score article trΖ°α»›c khi tαΊ‘o brief
Brief hiện "(cached β€” no API call)" BΓ¬nh thường β€” brief Δ‘Γ£ cache; npm run brief -- <id> --refresh để gọi lαΊ‘i Sonnet
Could not save angle file / template not found Copy templates/angle-template.md β†’ ~/Dev/vault/templates/angle-template.md; thΖ° mα»₯c output được tαΊ‘o tα»± Δ‘α»™ng
Missing required env var: TWITTERAPI_IO_KEY Điền TWITTERAPI_IO_KEY trong .env (lαΊ₯y tαΊ‘i twitterapi.io), hoαΊ·c chαΊ‘y npm run reply:analyze -- --skip-enrich để bỏ qua enrich
Content CSV not found Export content-latest.csv vΓ o ~/Dev/vault/projects/content-creator/analytics/raw/, hoαΊ·c dΓΉng --content=PATH
reply:analyze enrich bΓ‘o "failed: N" BΓ¬nh thường β€” lα»—i API 1 reply được skip + warn, cΓ‘c reply khΓ‘c vαΊ«n enrich; byHour/parentSizeCorrelation chỉ tΓ­nh tα»« reply enrich thΓ nh cΓ΄ng
DB migration log LαΊ§n Δ‘αΊ§u chαΊ‘y sau update sαΊ½ thαΊ₯y migration log β€” bΓ¬nh thường, tα»± xα»­ lΓ½

License

MIT

About

A local-first CLI tool for crypto content research. This is NOT an auto-posting bot.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors