mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-08-07 01:33:52 +00:00
5.3 KiB
5.3 KiB
AGENTS.md
Project
idx-cli — CLI tool for Indonesian stock market (IDX) analysis. Built in Rust for humans and AI agents. Single binary, schema-driven, functional architecture.
Stack
- Language: Rust (stable, via rust-overlay)
- CLI: clap 4 (derive)
- HTTP: ureq 3 (sync, no async runtime)
- Output: comfy-table, owo-colors
- DB: rusqlite (bundled SQLite, FTS5) — ownership module
- Config: TOML (
~/.config/idx/config.toml) - Cache: JSON file-based (
~/.cache/idx/) - Testing: cargo test, assert_cmd, predicates
- Hooks: prek (pre-commit: fmt+clippy, pre-push: test)
- VCS: jj (Jujutsu, colocated with git)
Structure
src/
├── main.rs # Entry point, command dispatch
├── cli/ # Command handlers (clap derive structs)
│ ├── stocks.rs # stocks quote/history/technical/fundamental/...
│ ├── config.rs # config get/set/init/path
│ ├── cache.rs # cache info/clear
│ └── ownership.rs # ownership import/query commands
├── api/ # Data providers (trait-based abstraction)
│ ├── mod.rs # MarketDataProvider trait + factory functions
│ ├── types.rs # All domain types (Quote, Ohlc, Fundamentals, ...)
│ ├── yahoo/ # Yahoo Finance provider (history/OHLCV)
│ └── msn/ # MSN Finance provider (quotes, fundamentals, ++)
├── analysis/ # Technical & fundamental analysis (pure functions)
├── ownership/ # Ownership intelligence module (SQLite-backed)
│ ├── types.rs # Ownership domain types
│ └── db.rs # Schema, migrations, queries
├── output/ # Rendering (table, json)
├── cache.rs # File-based TTL cache
├── config.rs # Config loading (flags > env > file > defaults)
└── error.rs # IdxError enum (thiserror)
Providers
- MSN = default provider (quotes, fundamentals, profile, earnings, financials, sentiment, insights, news, screener)
- Yahoo = automatic fallback for history/OHLCV (MSN doesn't support IDX history)
- Configurable:
IDX_PROVIDER=msn|yahoo,IDX_HISTORY_PROVIDER=auto|yahoo|msn
Current Status
- Automated coverage is healthy:
cargo testcurrently passes with 122 tests (86 unit, 36 integration). - Live
stockscommands are implemented and smoke-tested for:quote,history,technical,growth,valuation,risk,fundamental,compare,profile,financials,earnings,sentiment,insights,news,screen. stocks history --history-provider msnis intentionally unsupported for IDX;autofalls back to Yahoo.ownership import --fetch-bingis still intentionally unsupported; Bing client groundwork exists but the CLI path is deferred.
Known Hardening Gaps
- MSN-only commands still bypass the shared cache/offline path in
src/cli/stocks.rs;--offlineis not reliable forprofile/financials/earnings/sentiment/insights/news/screen. - Core quote flow has a verified
--offline --no-cachebug: stale cache can still be served. - Startup/config failures do not yet honor the JSON error contract; runtime failures do.
stocks screen --filterand--regionstill silently coerce invalid values instead of rejecting them.- Some live MSN output is incomplete or misleading:
profilecan return sparse fields.insights.last_updatedis still empty.financialstable output has malformed negative-number formatting in some rows.
Development
nix develop # enter dev shell
cargo build # build
cargo run -- stocks quote BBCA # run
cargo run -- -o json stocks history BBCA # JSON output
cargo test # test
cargo fmt --check && cargo clippy -- -D warnings # lint
Verification
cargo build # must compile
cargo clippy -- -D warnings # zero warnings
cargo test # all tests pass
Principles
- Schema-driven — define types first, build logic around them. Types are the spec.
- Functional approach — pure parse/transform functions (
parse_*,normalize_*), no hidden state. - Data types heavy — rich enums, newtypes, composite structs. Precision via integer representations (basis points for %, i64 for shares).
- Provider abstraction first — all data access should flow through traits/factories. Note: current MSN-only stock commands still instantiate
MsnProviderdirectly insrc/cli/stocks.rs; removing that split path is an active hardening target. - Sync only — no tokio/async. CLI tool, ureq is sufficient.
- Test with fixtures — never hit live APIs in tests. Mock provider + fixture JSON.
- Output contract — table to stdout (humans),
--output json(machines), errors to stderr. - Feature-gated modules —
ownershipfeature for SQLite dep, keeps base binary lean.
Docs
Start with the repo-visible docs:
FEATURE_SPEC.md— current hardening backlog and CLI truth-pass expectationsTODO.md— working task list, including latest smoke findingsdocs/ARCHITECTURE.md— provider/capability design and error strategydocs/CONVENTIONS.md— repo conventions