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.
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.
- 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
.mdvΓ 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:imagetα»« 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ΓΉngON 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:statusin 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 -- --verboselog 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αΊ£ngreply_tracking(idempotent theo Post id), ghi snapshot JSON ra vault cho dashboard Newsroom.--skip-enrichchαΊ‘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).
| 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 |
- Node.js 20+ (khuyαΊΏn nghα» LTS)
- npm (Δi kΓ¨m Node)
- Anthropic API key (cαΊ§n cho scoring + brief)
cd InkPilot
npm install
cp .env.example .env
# Sα»a .env: Δiα»n ANTHROPIC_API_KEY| 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
# ...# 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 --todayOutput 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.
# Generate brief cho article #42
npm run brief 42
# Bα» qua cache + regenerate Sonnet + ghi ΔΓ¨ file angle
npm run brief -- 42 --refreshOne-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.mdOutput:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# 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=14PhΓ’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.csvOutput: 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α»« vaultkol-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.
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 β β
# ...npm test # ChαΊ‘y 71 tests
npm run test:watch # Watch modesrc/
βββ 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
| 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.
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).
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).
- 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,--verboseflag - 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; refactoredlist.tscondition 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_trackingtable +npm run reply:analyze(X Analytics CSV β KOL niche β TwitterAPI.io enrichment β snapshot JSON for Newsroom);kol-niches.tsconfig;TWITTERAPI_IO_KEY - v0.5.1 β Fix
reply:analyzescope + 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 + raisemax_tokens1000 β 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_trackingdata layer)
| 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Γ½ |
MIT