Skip to content

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 (newreadstarreddraftedposteddismissed). 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 machinenewreadstarreddraftedposteddismissed.
  • Source upsertseedSources() 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 statusnpm 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 fetchnpm run fetch -- --verbose log per-feed: số item feed trả về, new vs duplicate sau mỗi nguồn.
  • Scoring diagnosticnpm 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 diagnosticnpm 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 inspectornpm 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

Packages

Contributors

Languages