Skip to content

Releases: 0xrsydn/idx-cli

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 11:03
a082a49

Broker summaries, bandarmology and foreign flow, from public data with no login or key.

New Features

  • idx stocks broker and the MCP tool get_broker_summary show a stock's top 10 buying and selling brokers over a day or a date range, with totals. You can filter by investor side and board. The data comes from Indo Premier (IPOT). (#62, #63)
  • idx stocks bandar and analyze_bandar read broker concentration as buy minus sell value for the top 1, 3, 5 and 10 brokers, and give a signal from big accumulation to big distribution. Several symbols make a ranked screen that stocks screen can pipe into. The thresholds are heuristics. (#64)
  • idx stocks flow and get_foreign_flow show foreign buying, selling and net value session by session. The data comes from IPOT by default; --source idx uses IDX's trading summary for exact share counts. (#65, #68)
  • --investor foreign|domestic now reads one investor side in broker and bandar, with that side's buy and sell totals. (#67)

Bug Fixes

  • Quotes and IDX screen rows now carry behind_session: true when the last trade is from before the latest IDX session. The quote table adds a note for these quotes, so a provider still showing the previous close after the session is no longer passed off as the latest price. (#71, #50)

Improvements

  • IPOT broker pages are parsed with html5ever and accepted only in IPOT's exact markup. A page that differs is rejected with an error and never misread. (#70)
  • IPOT pages for dates other than those requested are rejected before caching, and so are IDX trading summaries with no rows for the requested session. (#70)
  • Bandar readings use checked arithmetic, and the table says "No trades." only when no broker traded. (#70)
  • Flow and broker data share caches. Past sessions are cached for days and today for 5 minutes, and offline latest lookups skip uncached days. (#62, #65, #68)
  • The analyze_bandar top parameter lists its allowed values (1, 3, 5, 10) in the MCP schema. (#70)

Notes

  • stocks flow --source idx needs curl-impersonate. The default IPOT source does not.
  • New dependency: scraper 0.27 (html5ever). Servo's selectors, cssparser and dtoa-short are MPL-2.0 and used unmodified.
  • JSON output for quotes and screens adds the behind_session field; no existing field changed.

Full Changelog: v0.3.3...v0.4.0

v0.3.3

Choose a tag to compare

@github-actions github-actions released this 18 Oct 10:59
d6ff056

Upgrade from 0.3.2: ownership changes could report the wrong direction for investors with several accounts, and invalid dates were answered instead of rejected.

Bug Fixes

  • ownership changes and the get_ownership_changes tool compare an investor's total stake per ticker: KREN's KRESNA PRIMA INVEST, which added a second account, was reported as a decrease (944 → 401 bps) instead of an increase (944 → 1345). A corrected KSEI file for a month now replaces the original instead of mixing with it, and a file carrying several report dates compares each date on its own rows. (#53)
  • get_ownership_changes rejects dates that are not imported releases, are reversed, or are malformed; an empty from used to report every holder as new. (#53)
  • Investor search finds aliases, the raw names KSEI prints: PT ASTRA INTERNATIONAL TBK now finds ASTRA INTERNATIONAL. An empty investor name is an error instead of an arbitrary match. (#53)
  • ownership graph reaches every connected holder (holders whose id was a prefix of another's were dropped) and no longer slows down exponentially with depth. (#53)
  • ownership sync replaces the database in a single step, so an interrupted sync can no longer leave it missing; a snapshot whose holdings are missing is rejected before it replaces good data. A backup left by an interrupted older sync is restored, not overwritten. (#54)
  • Requests to MSN and Yahoo give up after 30 seconds instead of hanging, and ownership commands wait at most 30 seconds for another process's lock, so a stalled call cannot block every MCP tool. Downloads stop at 256 MiB as they arrive, including compressed ones. (#55)
  • Escape sequences in provider text (news titles, insights, errors, names) are neutralized before reaching the terminal. Descriptions and URLs with non-ASCII characters no longer crash table output. (#56)
  • In JSON mode, argument errors and warnings are JSON, so stderr stays parseable. idx config honors -o json; piped output stays plain text. (#56)
  • A "healthy" fundamental rating needs valuation and risk data; negative equity counts as high risk. (#57)
  • install.sh installs the newest release even when the releases API answers on one line. (#58)
  • cache clear removes symlinks without following them out of the cache. (#56)

Improvements

  • zip moves off a yanked release, to 9.0.4. (#52, #51)
  • Price data outside any plausible range is treated as missing instead of overflowing. (#55)
  • The snapshot publisher handles report titles with line breaks, checks its manifest before upload, and copies its database safely. (#58)
  • Release workflow actions are pinned to commit SHAs, and only the publishing job can write to releases. (#58)
  • Help text covers config keys and output, ownership changes date rules, and alias search. (#56)

Testing

  • Every fix has a regression test that fails on 0.3.2. The agent smoke test passes in Claude Code, Codex, pi, Hermes Agent, and opencode 1 and 2 through npx -y idx-mcp, ten cases each. Found by a full-repo audit with Codex (gpt-6.1-sol, xhigh) and re-reviewed until clean; Pullfrog's PR review found four more, fixed here.

Full Changelog: v0.3.2...v0.3.3

v0.3.2

Choose a tag to compare

@github-actions github-actions released this 16 Oct 10:11
1adf6e4

Upgrade from 0.3.1 if you run idx-mcp through npx, Hermes Agent, pnpm, or bun: 0.3.1 does not start there on npm 12.

New Features

  • News items carry relevance: company items about this ticker come first, newest first, then market items with general market news. The stocks news table gains an ABOUT column, and the get_company news section returns the same labels. (#47)
  • get_ownership_changes pages through large diffs with offset / next_offset and returns a summary over every row (counts by change type and the tickers with the most changes), so agents can answer overview questions without fetching every row. Rows are ordered by largest change first. (#48)

Bug Fixes

  • npx -y idx-mcp and npx idx-cli work on npm 12, pnpm 10+, and bun, which skip install scripts: the launcher now downloads the binary on first run instead of exiting with installed binary not found, which MCP clients reported as "Connection closed". This affected every Hermes Agent user. (#41, #42)
  • A first run with a read-only package directory, such as a root-owned sudo npm install -g on npm 12, installs the binary to a per-user cache instead of failing with EACCES. (#46)
  • Stopping the launcher during the first-run download (SIGTERM, SIGHUP, or SIGINT sent to its PID) stops the installer, removes the partial file, and exits by the same signal. (#46)
  • A local IDX_BINARY_URL binary is verified against IDX_BINARY_SHA256 after it is copied, so the installed bytes are the verified ones. (#46)
  • The user-cache fallback runs only from an absolute cache root, so an invalid XDG_CACHE_HOME or an empty HOME can never make the launcher run a binary from the current directory. (#46)
  • News is ordered by publish time rather than by timestamp text, so fractional seconds and time-zone offsets no longer move older items ahead. (#47)

Improvements

  • get_ownership_changes returns at most 300 rows per page (previously 2000, about 200 KB), which no longer overflows agents' tool output. The over-limit error points to offset and summary. (#48)
  • News is fetched wider (at least 50 items), so this company's articles further down MSN's feed are found. MSN's stock tags are combined with the ticker and company name to find them. (#47)

Testing

  • The agent smoke test runs Claude Code, Codex, pi, Hermes Agent, and opencode 1 and 2 against npx -y idx-mcp, each from a cold npm cache in an empty directory. Each agent must install the binary itself, and ten cases call every MCP tool except ownership_sync, which needs --allow-sync. All six harnesses pass on this release. (#44)
  • The npm smoke test covers installs without postinstall, read-only installs, and a planted binary that must never run. (#46)

Full Changelog: v0.3.1...v0.3.2

v0.3.1

Choose a tag to compare

@0xrsydn 0xrsydn released this 15 Oct 03:15

Security and data-safety fixes for 0.3.0. Upgrade from 0.3.0; 0.3.0 is yanked on crates.io and deprecated on npm.

Security

  • Path traversal via ticker symbols. A ticker such as ../../x was used directly in cache file names, so idx could read or delete .json files outside its cache directory. Through idx-mcp, a single tool call from a prompt-injected agent was enough. Tickers are now validated (invalid ticker symbol, exit 2) and cache file names are encoded.

Ownership database

  • A cross-process lock (<db>.lock) now guards the ownership database: sync installs, imports and entity edits take it exclusively, reads take it shared. Before, a sync could replace the database under an active import or reader and lose data.
  • Sync downloads without holding the lock, and downloads now time out (15 s connect, 10 min total) instead of hanging.
  • A symlinked ownership.db_path keeps its symlink: sync updates the real file and shares its lock.
  • A rebuilt snapshot never replaces a local database that holds more releases than it does.

MCP

  • Input limits: at most 20 symbols per call (duplicates collapsed), caps on limit, at most 4 concurrent tool calls. The tool schemas state the limits.

Robustness

  • Atomic cache writes; per-client Yahoo cookie files.
  • Size caps on ZIP entries and XLSX workbooks; two parser inputs that could crash or overflow now return errors.

Other

  • Minimum supported Rust version is now 1.89 (for std file locks).
  • tests/agents/agent-smoke.sh: opt-in smoke test that drives real coding agents (Claude Code, Codex, pi, Hermes, opencode) against idx-mcp.

v0.3.0 - idx-mcp server, idx-core library, agent-native output

Choose a tag to compare

@0xrsydn 0xrsydn released this 14 Oct 20:05
386a63c

Highlights

  • New: idx-mcp, an MCP server. It serves the same market, financial and ownership data to MCP clients over stdio, through 11 tools: get_quotes, get_price_history, screen_stocks, get_company, analyze_stock, compare_stocks, get_shareholders, get_investor_holdings, search_investors, get_ownership_changes, ownership_status.
    • Install with claude mcp add idx -- npx -y idx-mcp, cargo install idx-mcp, or nix profile install github:0xrsydn/idx-cli#idx-mcp.
    • Live results come as {data, source, fetched_at, stale}.
    • Errors use the CLI's {error, code, message} body.
    • The server shares idx's config, cache and ownership database.
    • --allow-sync adds an ownership_sync tool.
  • Agent-native CLI output. idx now prints JSON when stdout is not a terminal, and tables when it is. Agents and scripts get structured data without flags. JSON is compact when piped. -o jsonl prints one record per line. No color codes appear when piped.
  • idx-core library. All data access, caching and analysis now live in a separate crate shared by idx and idx-mcp.

Breaking changes

  • Default output when piped is JSON. Use -o table, IDX_OUTPUT=table, or general.output = "table" to get tables back. A config created by idx config init before 0.3 pins output = "table"; run idx config set general.output auto to switch to the new behavior.

  • Exit codes by error class. Before 0.3, every error exited with 1.

    Exit Meaning
    2 invalid input or config
    3 not found, no data, or no cached data offline
    4 upstream unavailable; retry later
    5 unsupported
    1 other

CLI

  • stocks quote - and stocks compare - read symbols from stdin, separated by whitespace or commas. Example: idx stocks screen --filter high-dividend | jq -r '.[].symbol' | idx stocks compare -.
  • Financial statement line items come out in a stable order in JSON.
  • Fixed: tables with colored cells (signals, change types) had a ragged right border in terminals.

Ownership

  • Fixed: the IDX workbook stores the share code TRUE (TRINITI DINAMIK) as a boolean cell, so its holders were imported under ticker 1.
    • The published snapshot for 2026-09-30 has been rebuilt. The rebuild also corrects the bogus August→September changes for TRUE and 1.
    • With 0.3, idx ownership sync picks up the rebuild automatically.
    • On 0.2.x, run idx ownership sync --force once.
  • Sync now updates a database that is still byte-identical to an earlier build of the same snapshot. The manifest gains an optional replaces_sqlite_sha256 field, which older clients ignore. A database you imported or edited locally still needs --force.

Distribution

  • Release assets add idx-mcp-<platform> binaries next to idx-<platform>, all listed in SHA256SUMS.
  • New npm package idx-mcp, alongside idx-cli. New crates idx-core and idx-mcp.
  • Rust: idx builds with 1.85+, and idx-mcp needs 1.88+.

Verification

  • 143 golden outputs (every command in table and JSON, plus error cases) are unchanged except for the documented output-default and exit-code changes.
  • Live A/B checks against 0.2.4 match.
  • Each MCP tool's data equals the CLI's JSON.

v0.2.4 - XLSX ownership data, curl/npm install

Choose a tag to compare

@github-actions github-actions released this 25 Sep 22:42
b88425f

Highlights

  • Ownership data is current again. Since June 2026 IDX publishes the monthly "Pemegang Saham di Atas 1%" list as XLSX on the Data Kepemilikan Saham page instead of a PDF announcement. idx ownership discover finds it there and idx ownership import reads it. The published snapshot (idx ownership sync) now covers 2026-06-30, 2026-07-31 and 2026-08-31.
  • New install channels: curl -fsSL https://raw.githubusercontent.com/0xrsydn/idx-cli/main/install.sh | sh and npm (npx idx-cli, npm i -g idx-cli). Both use prebuilt binaries with SHA-256 verification.
  • Sync accepts larger snapshots. v0.2.3 and earlier cap snapshot downloads at 10 MiB. This version accepts up to the manifest's size (at most 1 GiB), which leaves room for more months of history later.

Ownership

  • XLSX parser for the above-1% holder register (#25). Only the exact 12-column layout is accepted, so the daily above-5% and investor-type workbooks are rejected instead of mis-imported. Both the Feb/Mar 2026 INVESTOR_TYPE and the later INVESTOR_CLASSIFICATION headers are handled.
  • Discovery merges the announcement API with the data page (#26). Downloads retry across curl-impersonate browser profiles, since IDX's Cloudflare rejects curl_chrome142 on the new page.
  • ownership import --url accepts .xlsx.
  • Snapshot sync: the download is bounded by the manifest's size_bytes, and a body larger than advertised is rejected (#31).

Snapshot publishing (maintainers)

  • build-latest-ownership-snapshot.sh --history <n> includes earlier months (#27). --max-snapshot-bytes (default 10 MiB) refuses snapshots that released clients can't download (#31).
  • Idempotent, packaged publisher: nix build .#ownership-publisher gives idx-ownership-publish and idx-ownership-freshness. Every run ends in one RESULT: line (#29). Upload verification and partial-publish recovery (#30).

Distribution

  • Release workflow builds static musl Linux (x64, arm64) and macOS (arm64, x64) binaries, plus SHA256SUMS and install.sh (#22, #24).
  • npm wrapper with checksum-verified postinstall (#22). pnpm 10+ and bun need --allow-build / --trust.

Compatibility

  • The snapshot manifest is still schema v1. v0.2.3 clients keep syncing as long as snapshots stay at or below 10 MiB, which the publisher enforces.
  • Discover JSON gains format and as_of_date fields; existing fields are unchanged.

v0.2.3 - July 2026 KSEI Spaced-Header Parser Fix

Choose a tag to compare

@0xrsydn 0xrsydn released this 31 Jul 19:27
603c0e4

Fixes

  • handles the new spaced-header KSEI PDF layout (SHARE CODE, INVESTOR CLASSIFICATION) that broke schema classification
  • normalizes spaced header text before schema classification so both underscore (SHARE_CODE) and spaced layouts parse
  • adds INVESTOR_CLASSIFICATION to schema markers and header labels
  • satisfies clippy 1.97 lints that failed the ubuntu CI step (filter, sort_by_key(Reverse), ?)

Scope

  • published from commit 603c0e4 (main, after PR #21 merge)
  • adds a test fixture from the live June 2026 KSEI PDF and a spaced-header test case
  • all 222 tests pass (143 unit + 79 integration), clippy + fmt clean
  • snapshot data asset unchanged: latest KSEI above-1% report is still as_of 2026-05-29; the parser fix enables future June/July imports once IDX publishes them

Ownership Snapshot Current

Choose a tag to compare

@0xrsydn 0xrsydn released this 12 Apr 06:58
71f283e

Stable release for idx ownership snapshot artifacts consumed by idx ownership sync.

v0.2.2 - April 2026 KSEI Parser Fix

Choose a tag to compare

@0xrsydn 0xrsydn released this 12 Apr 07:49

Fixes

  • handles April 2026 KSEI PDFs that omit zero-valued scrip columns on some holder rows
  • defaults missing component share fields to zero while still requiring total shares
  • restores successful import and sync against the live April 2026 KSEI ownership file format

Scope

  • published from commit 04eaa75
  • includes the 0.2.2 version bump that was already shipped to crates.io
  • this release object backfills the missing GitHub tag/release for that published crate version

v0.2.1 - Ownership Sync Bootstrap

Choose a tag to compare

@0xrsydn 0xrsydn released this 12 Apr 07:49

Highlights

  • adds idx ownership discover to locate the latest supported IDX above-1 shareholder register PDF
  • adds idx ownership import --url <pdf-url> for direct remote import
  • adds idx ownership sync for maintained snapshot-based bootstrap and refresh
  • adds local archive ZIP/TXT ingest as a fallback backstop path
  • expands smoke coverage and fixture-backed ownership tests

Notes

  • stocks remains MSN-first, with Yahoo retained for history fallback
  • this release is being backfilled on GitHub so release objects match the existing tag history