sectors-cli

module
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2026 License: MIT

README

sectors-cli

A command-line client for the Sectors Financial API v2 covering Indonesia (IDX), Singapore (SGX), Malaysia (KLSE), and Indonesian mining data.

It is built to be driven by AI agents as well as humans: output defaults to the API's raw JSON (pretty-printed in a terminal, compact when piped), failed requests exit non-zero with a JSON error on stderr, and --help on any command documents its parameters straight from the API spec — so an agent can discover capabilities by reading help.

Install

# Released binary (Linux/macOS)
curl -fsSL https://raw.githubusercontent.com/emrsyah/sectors-cli/main/install.sh | sh

# Or with Go
go install github.com/emrsyah/sectors-cli/cmd/sectors@latest

Or download a prebuilt archive for your platform from the releases page.

Quick start

# Build from source
go build -o sectors ./cmd/sectors

# Authenticate (get a key at https://sectors.app/api)
./sectors auth login --api-key <your-key>      # or: export SECTORS_API_KEY=<key>
./sectors auth status

# Use it
./sectors idx company report BBCA
./sectors idx company report BREN --sections overview,valuation
./sectors idx company report BBCA -o pretty

Output formats (-o / --output)

value behaviour
auto (default) pretty JSON on an interactive terminal, compact JSON when piped (best for agents)
json compact single-line JSON
pretty indented JSON
table ASCII table for list responses (arrays or {results:[…]}); falls back to pretty JSON for nested/single-object responses
sectors idx transaction daily BBCA --start 2026-06-20 --end 2026-06-26 -o table
sectors idx companies --q "top 5 banks by revenue" | jq '.results[].symbol'

Failed requests print a JSON error to stderr and exit non-zero, so scripts and agents can branch on the result.

Agent integration

This CLI is designed to be driven by AI agents.

Tool manifest. Generate tool/function-calling schemas for every command, straight from the command tree (so they never drift from the real flags):

sectors manifest --format anthropic        # tool-use definitions
sectors manifest --format openai           # function-calling
sectors manifest --format json             # neutral
sectors manifest --filter "idx_*"          # export a subset

Each leaf command becomes one tool (e.g. idx_company_report) with a JSON-Schema input_schema: positional args and flags become typed properties, required flags land in required, and a|b|c choice flags become enums.

Structured errors. Failures emit a JSON envelope on stderr with a stable category and retryable so an agent can branch without scraping text:

{"error":"request failed","status":429,"category":"rate_limited","retryable":true}

Exit codes mirror the category, so shell/agent logic can branch without parsing JSON at all:

code meaning
0 success
1 client-side / config / transport error
2 invalid input (400/422)
3 auth (401/403)
4 not found (404)
5 rate limited (429)
6 server error (5xx)

Automatic retries. Transient failures (429, 500, 502, 503, 504, and network errors) are retried with exponential backoff + jitter, honoring Retry-After. Tune with --retries (default 3) and --retry-max-wait (default 10s); set --retries 0 to disable.

Response shaping (token economy). Shrink responses before they reach the model's context window:

# keep only the fields you need (dotted paths; key[] maps over an array)
sectors idx company report BBCA --select overview.market_cap,valuation
sectors idx companies --where "sub_sector='banks'" --select "results[].symbol"

# cap a list (adds "_truncated": true to paginated responses)
sectors idx news list --max 5

# just the count
sectors idx list subsectors --count        # -> {"count": 33}

These run client-side after the request, so they compose with the server-side --sections / --limit filters. In practice --select cuts a full company report from ~56 KB to a few dozen bytes.

Caching & observability

Caching. GET responses are cached on disk to cut latency, cost, and rate-limit pressure for the repetitive reads agents make. TTLs vary by endpoint volatility (reference lists ~24h, intraday data ~1m, reports ~5m). Override or inspect:

sectors idx list subsectors --no-cache       # bypass the cache
sectors idx daily BBCA --cache-ttl 30s        # uniform TTL override
sectors cache path                            # where the cache lives
sectors cache clear                           # wipe it

Tracing. --verbose (-v) logs each request to stderr; --dry-run prints the request that would be sent (API key redacted) without calling the API:

$ sectors idx list subsectors -v
GET https://api.sectors.app/v2/subsectors/ -> 200 1ms (cache hit)

$ sectors idx company report BBCA --dry-run
{"dry_run":true,"method":"GET","url":".../v2/company/report/BBCA/","headers":{"Authorization":"***redacted***"}}

Shell completions

Cobra generates completions for bash, zsh, fish, and PowerShell:

sectors completion zsh > "${fpath[1]}/_sectors"     # zsh
sectors completion bash | sudo tee /etc/bash_completion.d/sectors   # bash
sectors completion fish > ~/.config/fish/completions/sectors.fish   # fish

Once installed, completing the -o/--output flag suggests the valid formats with descriptions (auto, json, pretty, table) — e.g. sectors … -o <TAB>.

Releasing

Versioned cross-platform binaries are built with goreleaser (.goreleaser.yaml). The version is injected via ldflags and surfaced by sectors --version.

goreleaser release --snapshot --clean   # local snapshot build
git tag v0.1.0 && goreleaser release --clean   # tagged release

Tests

go test ./...

Architecture

Layer What
API client Generated by oapi-codegen from sectors-schema.json (the upstream OpenAPI 3.0 spec). 63 typed operations in internal/sectors/sectors.gen.go.
CLI framework spf13/cobra — command tree, flags, auto --help and shell completions.
Config / auth internal/config — resolves the API key with precedence: --api-key flag → $SECTORS_API_KEY → config file (<user-config-dir>/sectors/config.yaml, 0600).
Output internal/output — raw-JSON renderer with TTY auto-detection (pretty on a terminal, compact when piped) and structured JSON errors on stderr.
Regenerating the client

tools/fixspec sanitizes the upstream spec into sectors-schema.fixed.json before generation (the pristine sectors-schema.json is never mutated). It:

  1. drops malformed paths (a required path parameter missing from the URL template), which oapi-codegen rejects; and
  2. empties every response body schema so response bodies generate as interface{}. The upstream response schemas are frequently inaccurate (arrays typed as objects, string-vs-number, offset-less timestamps), which would make the generated response parser reject otherwise-valid payloads. The CLI emits the raw response body and never reads the typed fields, so untyped bodies are strictly safer. Request parameter types are untouched.
go generate ./...   # runs fixspec, then oapi-codegen

Command tree

  • auth login | status
  • idx — Indonesia (complete): ✅
    • companies (screener: --where / --q / --order-by / --limit) · free-float
    • company report | segments | financials | corporate-actions | shareholders | ipo-performance | quarterly-dates
    • subsector report
    • brokers activity | activity-top | summary | summary-top | registry | top | foreign-flow
    • transaction daily | idx-total | index-daily
    • ranking most-traded | top-changes
    • news list | filings | suspensions
    • list industries | subindustries | subsectors | tags | segments-companies
  • sgx — Singapore (complete): ✅ companies (screener) · top · report · sectors · tags · news · filings · buybacks · short-sell · daily
  • klse — Malaysia (complete): ✅ companies --sector · top · report · sectors
  • mining — Mining extension (complete): ✅
    • companies list | get | financials | ownership | performance
    • commodities list | price | exports | global | sales-destination
    • sites list | get · production total · reserves index | get
    • licenses list · auctions list | get · contracts list

All 63 API operations are wired to commands.

Code layout

Each market is its own package exposing a NewCmd() constructor; cmd/cmdutil holds the shared client factory, response/error rendering, and optional-flag → pointer helpers. Adding a market is a new cmd/<market>/ package wired into cmd/root.go.

cmd/
├── root.go            # global flags, Execute, wires market packages
├── auth.go
├── cmdutil/           # NewClient, Emit, Fail, Do, Opt{Str,Int,Bool,Float,Enum}
├── idx/               # company.go companies.go brokers.go market.go news.go list.go
├── sgx/               # companies.go reference.go news.go transaction.go
├── klse/              # klse.go
└── mining/            # companies.go commodities.go sites.go licenses.go

See sectors-docs/_ENDPOINT_INVENTORY.md for the full endpoint → command map.

Directories

Path Synopsis
cmd
Package cmd assembles the sectors CLI command tree.
Package cmd assembles the sectors CLI command tree.
cmdutil
Package cmdutil holds helpers shared across every command package: building an authenticated client, rendering responses/errors, and turning optional flags into the pointer-typed query parameters the generated client expects.
Package cmdutil holds helpers shared across every command package: building an authenticated client, rendering responses/errors, and turning optional flags into the pointer-typed query parameters the generated client expects.
idx
Package idx implements the `sectors idx` command group: Indonesia Stock Exchange data (companies, reports, brokers, transactions, rankings, news).
Package idx implements the `sectors idx` command group: Indonesia Stock Exchange data (companies, reports, brokers, transactions, rankings, news).
klse
Package klse implements the `sectors klse` command group: Bursa Malaysia (KLSE) data — companies by sector, rankings, and company reports.
Package klse implements the `sectors klse` command group: Bursa Malaysia (KLSE) data — companies by sector, rankings, and company reports.
mining
Package mining implements the `sectors mining` command group: the Indonesian mining-sector extension — companies, commodities & trade, production & sites, and licenses, auctions & contracts.
Package mining implements the `sectors mining` command group: the Indonesian mining-sector extension — companies, commodities & trade, production & sites, and licenses, auctions & contracts.
sectors command
sgx
Package sgx implements the `sectors sgx` command group: Singapore Exchange (SGX) data — screener, reports, news, filings, and transactions.
Package sgx implements the `sectors sgx` command group: Singapore Exchange (SGX) data — screener, reports, news, filings, and transactions.
internal
config
Package config resolves runtime configuration for the sectors CLI.
Package config resolves runtime configuration for the sectors CLI.
output
Package output renders API responses for the sectors CLI.
Package output renders API responses for the sectors CLI.
sectors
Package sectors contains the generated, typed client for the Sectors Financial API v2 plus thin hand-written helpers (auth, base URL).
Package sectors contains the generated, typed client for the Sectors Financial API v2 plus thin hand-written helpers (auth, base URL).
tools
fixspec command
Command fixspec sanitizes the upstream Sectors OpenAPI spec so oapi-codegen can consume it, without mutating the pristine source file.
Command fixspec sanitizes the upstream Sectors OpenAPI spec so oapi-codegen can consume it, without mutating the pristine source file.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL