fix(actions): JSON kinds match --kind, and harden parsing and ranges

- JSON named kinds by their Rust names (public_expose, tender_offer,
  stock_dividend, reverse_split) while --kind and MCP take expose, tender,
  stock-dividend, reverse-split, so an output kind could not be passed
  back. JSON now uses the input names; old cache entries still read, and
  --kind also accepts underscores.
- {"dividend": null, "today": "..."} failed to parse and aborted the
  whole command; a null list beside scalars now reads as none.
- An extreme --from panicked on the default 30 days; it is an error now.
  The 366-day limit let 367 days through; it counts both ends now.
- An entitlement without a cum date sat on its ex date under a note that
  calls DATE the cum date. The table marks it (ex) and says what that
  means; JSON leaves cum_date out, as before, and the docs say so.
- A dividend's currency was ignored; one not in IDR now carries currency
  and the table shows it instead of Rp.
- The live check no longer fails a quiet month's empty calendar.

Claude-Session: https://claude.ai/code/session_01RqPPVeVDrnLoP7NUZmLRxY
This commit is contained in:
Rasyidan Akbar F. 2026-11-04 17:35:51 +07:00
commit 1e5561e990
10 changed files with 131 additions and 24 deletions

View file

@ -134,8 +134,12 @@ contract() {
echo 'type == "array" and all(.[]; (.title | type == "string") and (.url | type == "string"))' ;;
"stocks orderbook "*)
echo '(.symbol | type == "string") and (.price | type == "number") and (.market_status | type == "string") and (.bids | type == "array") and (.offers | type == "array")' ;;
"stocks actions "*|"stocks calendar"*)
# The smoke symbol always has dividends on record; a quiet month can
# leave the calendar empty.
"stocks actions "*)
echo 'type == "array" and length > 0 and all(.[]; (.symbol | type == "string") and (.kind | type == "string") and (.date | type == "string"))' ;;
"stocks calendar"*)
echo 'type == "array" and all(.[]; (.symbol | type == "string") and (.kind | type == "string") and (.date | type == "string"))' ;;
"stocks broker "*)
echo '(.symbol | type == "string") and (.buyers | length > 0) and (.sellers | length > 0) and all(.buyers[]; (.code | type == "string") and (.value | type == "number")) and (.total_value | type == "number")' ;;
"stocks bandar "*)