@invinite-org/invinite-data-cli 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -214,9 +214,10 @@ command. A handful of commands are hand-written because they do more than one ca
214
214
  | `segments` | `list`, `list-detailed` |
215
215
  | `filings` | List, natural-language search, sections, form types |
216
216
  | `earnings` | Calendar, events, live calls, transcripts, Q&A, participants, analysts, guidance and KPI extractions, diff, metrics, prosody, price moves during the call, media, documents, search, company IR documents |
217
+ | `news` | News of US companies from SEC filings and their own newsrooms: `list` (cursor-paged), `get` (full text + attribution), `text` (citable blocks), `developments`, `search` (passages; off until the API enables it), `asset-download` |
217
218
  | `ownership` | 13F holdings by company / investor, institutions, transactions |
218
219
  | `insider-trades`, `ipos`, `market`, `metadata` | Insider transactions, IPOs, market holidays, available metric and filing-section ids |
219
- | `webhooks` | Earnings-call webhook subscriptions (PRO) |
220
+ | `webhooks` | Earnings-call and `news.published` webhook subscriptions |
220
221
  | `usage`, `health`, `status` | Your account's usage (free), API liveness and status (no key) |
221
222
 
222
223
  ```bash
@@ -308,9 +309,35 @@ coincidence, not attribution of cause.
308
309
 
309
310
  ---
310
311
 
312
+ ### news
313
+
314
+ News of US companies from SEC EDGAR filings (`rights: public_record`) and the companies' own newsrooms
315
+ (`rights: issuer`); wire services are never a source. `--ticker` / `--cik` = items that mention a company,
316
+ `--publisher <cik>` = items the company published itself (`--publication-type`, `--issuer-category`, `--issuer-tag`
317
+ narrow its own publications). The list is cursor-paged: `--all` follows `next_url`, or pass `next_cursor` as
318
+ `--cursor` with the same filters; the default window is the last 7 days (`--from` / `--to`, ≤ 92 days).
319
+
320
+ Every item carries `attribution` (publisher, `source_url`, `published_at`, EDGAR form + accession, `statement`):
321
+ wherever you show a headline or text, show its publisher, link and date with it. `news get` (STANDARD) has the
322
+ `body_text` (`content_status: no_text` = headline and link only); `news text` serves it in blocks (a `409
323
+ revision_changed` = the item was corrected; start again without `--cursor`). Process text with an AI model only when
324
+ `model_processing_allowed` is `true`. `news asset-download` returns a URL valid for at most 60 seconds.
325
+
326
+ ```bash
327
+ invd news list --ticker NVDA --json
328
+ invd news list --publisher 1045810 --publication-type press_release --from 2026-10-01 --all --json
329
+ invd news get --id <id> --json
330
+ invd news text --id <id> --all --json
331
+ invd news developments --publisher 1045810 --topic product_launch --json
332
+ invd news search -q "data center revenue" -t NVDA --json
333
+ invd ws listen --news --tickers NVDA
334
+ ```
335
+
336
+ ---
337
+
311
338
  ### webhooks
312
339
 
313
- Earnings-call webhook subscriptions (PRO): signed, retried `POST`s of the call lifecycle to your HTTPS endpoint. Events: `earnings_call.scheduled`, `.rescheduled`, `.started`, `.ended`, `.transcript_provisional`, `.transcript_ready`, `.transcript_corrected`, `.assets_ready`, `.keyword_hit` (one delivery per mention of one of the subscription's keywords on a live call, with the speaker, `start_ms` and the sentence), `.guidance_flash` (a guidance number spoken live, before the final transcript), and `ping`. Deliveries carry `X-Invinite-Signature: t=…,v1=…` (HMAC-SHA256 of `<t>.<raw body>` with the secret) and are retried after 1 min, 5 min, 30 min, 2 h, 6 h, 12 h and 24 h.
340
+ Earnings-call webhook subscriptions (PRO): signed, retried `POST`s of the call lifecycle to your HTTPS endpoint. Events: `earnings_call.scheduled`, `.rescheduled`, `.started`, `.ended`, `.transcript_provisional`, `.transcript_ready`, `.transcript_corrected`, `.assets_ready`, `.keyword_hit` (one delivery per mention of one of the subscription's keywords on a live call, with the speaker, `start_ms` and the sentence), `.guidance_flash` (a guidance number spoken live, before the final transcript), `news.published` (STANDARD and above: one delivery per new news item, `data.item` = a `news list` row, filtered by the CIKs it mentions), and `ping`. Deliveries carry `X-Invinite-Signature: t=…,v1=…` (HMAC-SHA256 of `<t>.<raw body>` with the secret) and are retried after 1 min, 5 min, 30 min, 2 h, 6 h, 12 h and 24 h.
314
341
 
315
342
  `webhooks create` and `webhooks update` take the request body as `--body '<json>'` or `--body-file <path>` (`-` reads
316
343
  stdin); the other commands take the subscription as `--id`. `create` **prints the signing secret once**; `rotate-secret`
@@ -320,6 +347,7 @@ prints a new one (the old one stays valid for 5 minutes); `test` queues a signed
320
347
  ```bash
321
348
  invd webhooks create --body '{"url":"https://hooks.example.com/invinite","events":["earnings_call.transcript_ready","earnings_call.started"],"filters":{"ciks":["320193"]}}'
322
349
  invd webhooks create --body '{"url":"https://hooks.example.com/alerts","events":["earnings_call.keyword_hit"],"filters":{"keywords":["tariffs","buyback"]}}' # every company
350
+ invd webhooks create --body '{"url":"https://hooks.example.com/news","events":["news.published"],"filters":{"ciks":["1045810"]}}'
323
351
  invd webhooks update --id <id> --body '{"keywords":["tariffs","china","buyback"]}'
324
352
  invd webhooks update --id <id> --body '{"active":false}'
325
353
  invd webhooks test --id <id>
@@ -334,7 +362,7 @@ Real-time WebSocket streaming.
334
362
 
335
363
  #### `ws listen`
336
364
 
337
- Listen to real-time SEC filing notifications, or with `--earnings` follow one earnings call's live transcript (PRO), or with `--all-live --keywords` get keyword alerts across every live call. Automatically reconnects on disconnection with exponential backoff.
365
+ Listen to real-time SEC filing notifications, or with `--earnings` follow one earnings call's live transcript (PRO), or with `--all-live --keywords` get keyword alerts across every live call, or with `--news` get new news items as they are published (STANDARD). Automatically reconnects on disconnection with exponential backoff.
338
366
 
339
367
  | Option | Description |
340
368
  |--------|-------------|
@@ -348,6 +376,12 @@ Listen to real-time SEC filing notifications, or with `--earnings` follow one ea
348
376
  | `--keyword-match exact\|stem` | `exact` (default) matches the word; `stem` also its inflections (`tariff` hits "tariffs") |
349
377
  | `--speaker-roles <list>` | Only hits by these speakers: `executive`, `ir_host`, `analyst`, `operator` |
350
378
  | `--min-rank <n>` | With `--all-live`: only companies ranked ≤ n by market cap |
379
+ | `--news` | New news items (channel `news.live`); excludes `--earnings`, `--all-live` and the live-call flags |
380
+ | `--tickers <list>` | With `--news`: items mentioning these tickers (≤ 50; `BRK.B` = `BRK-B`; with `--ciks` either matches). Default: every company |
381
+ | `--ciks <list>` | With `--news`: items mentioning these CIKs (≤ 50, padded or not) |
382
+ | `--news-kinds <list>` | With `--news`: only these kinds (`earnings_results`, `results_date`, `call_announcement`, `event_announcement`, `guidance`, `m_and_a`, `material_agreement`, `management_change`, `dividend`, `capital_markets`, `legal_spam`, `promo`, `other`) |
383
+ | `--news-sources <list>` | With `--news`: `edgar` (SEC filings) and / or `ir` (company newsrooms) |
384
+ | `--earnings-news` | With `--news`: earnings news only |
351
385
 
352
386
  ```bash
353
387
  invd ws listen
@@ -379,6 +413,14 @@ invd ws listen --all-live --keywords tariffs --json | jq -r 'select(.type=="keyw
379
413
  invd ws listen --earnings <event_id> --prices
380
414
  ```
381
415
 
416
+ **Live news.** `--news` subscribes to `news.live` and prints one line per new item — publication time (UTC), source (`SEC EDGAR` or the newsroom's host), tickers, headline, link — and ignores the filing broadcasts; `--json` emits every news frame as one JSON line (`news_item.item` = a `news list` row with its `attribution`). Items published while disconnected are not replayed: `invd news list` has them. A plan without the channel ends the run (`news.live needs the STANDARD plan`).
417
+
418
+ ```bash
419
+ invd ws listen --news --tickers NVDA
420
+ # 2026-10-29 13:03:22Z nvidianews.nvidia.com NVDA NVIDIA Announces Rubin Platform https://nvidianews.nvidia.com/news/…
421
+ invd ws listen --news --ciks 1045810 --news-sources ir --json | jq -r 'select(.type=="news_item") | .item.title'
422
+ ```
423
+
382
424
  Finals are named from the newest speaker-name snapshot (`Speaker A` until a name is known). A `gap` line marks a seq range with no final yet (a late final may still follow on the same subscription, so finals can print slightly out of order); `resume_unavailable` means missed finals cannot be replayed right now — live delivery continues and the API back-fills them once it can. Neither needs a re-subscribe. After a reconnect the listener resumes after the last final it printed; it exits once the final transcript is ready (`invd earnings transcript --event-id <id>`). With `--json` every frame is one JSON line (NDJSON), e.g. `invd ws listen --earnings 320193 --json | jq -r 'select(.type=="transcript_segment") | .text'`.
383
425
 
384
426
  ---
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "invinite-financial-data",
3
- "description": "Fetch and analyze financial data using the Invinite Data API — company fundamentals, financial statements, SEC filings, earnings calls (transcripts, guidance, Q&A, live calls), institutional ownership, insider trades, and more.",
4
- "version": "0.4.5",
3
+ "description": "Fetch and analyze financial data using the Invinite Data API — company fundamentals, financial statements, SEC filings, earnings calls (transcripts, guidance, Q&A, live calls), company news, institutional ownership, insider trades, and more.",
4
+ "version": "0.4.6",
5
5
  "author": {
6
6
  "name": "Invinite"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: invinite-data
3
- description: Fetches financial data from the Invinite Data API for analysis. Use this agent whenever you need company financials, SEC filings, institutional ownership, insider trades, financial ratios, growth metrics, earnings calls (calendar, transcripts, guidance and KPIs, Q&A, press releases, slides), or any stock/company data. Delegate to this agent when the user asks for financial data retrieval, company research, or comparative financial analysis — even if they don't mention "Invinite" explicitly. This agent knows how to efficiently query the right endpoints, combine data from multiple sources, and return structured results ready for analysis.
3
+ description: Fetches financial data from the Invinite Data API for analysis. Use this agent whenever you need company financials, SEC filings, institutional ownership, insider trades, financial ratios, growth metrics, earnings calls (calendar, transcripts, guidance and KPIs, Q&A, press releases, slides), company news (SEC filings and the companies' own newsroom announcements), or any stock/company data. Delegate to this agent when the user asks for financial data retrieval, company research, or comparative financial analysis — even if they don't mention "Invinite" explicitly. This agent knows how to efficiently query the right endpoints, combine data from multiple sources, and return structured results ready for analysis.
4
4
  tools: Bash(invd *), Read, Glob, Grep
5
5
  skills:
6
6
  - invinite-data-cli
@@ -44,6 +44,7 @@ Common multi-step patterns:
44
44
  - **Comparative analysis**: metadata metrics (first) + financials snapshot with multiple tickers + metrics ratios for each
45
45
  - **Earnings call review**: earnings events (first, for the `event_id`) → then in parallel press-release + extractions `--kind guidance` + extractions `--kind kpi` + qa + diff (+ optionally price-attribution: minute price moves next to what was said — temporal coincidence, not cause)
46
46
  - **Guidance tracking**: earnings guidance-history `--metric <metric>` across calls + extractions of the latest call
47
+ - **Company announcements**: news list `--publisher <cik>` (what the company published itself; `--ticker` = items mentioning it) → news get `--id <id>` for `body_text` + news developments `--publisher <cik>`; keep each item's `attribution` (publisher, `source_url`, `published_at`, EDGAR form + accession) in the results so the caller can cite it
47
48
 
48
49
  ## Output format
49
50
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: invinite-financial-data
3
- description: Fetch financial data through the Invinite Data API MCP connector or invd CLI. Use whenever the user wants company information, financial statements, SEC filings, institutional ownership, insider trades, IPO data, market holidays, financial metrics, earnings calls, or other stock/company data, including requests mentioning tickers, CIKs, balance sheets, income statements, cash flows, 10-K, 10-Q, ratios, CAGR, growth rates, dividends, stock splits, institutional holdings, call transcripts, earnings guidance, KPIs, Q&A, analysts, live calls, slides, or press releases.
3
+ description: Fetch financial data through the Invinite Data API MCP connector or invd CLI. Use whenever the user wants company information, financial statements, SEC filings, institutional ownership, insider trades, IPO data, market holidays, financial metrics, earnings calls, company news, or other stock/company data, including requests mentioning tickers, CIKs, balance sheets, income statements, cash flows, 10-K, 10-Q, ratios, CAGR, growth rates, dividends, stock splits, institutional holdings, call transcripts, earnings guidance, KPIs, Q&A, analysts, live calls, slides, press releases, company announcements, newsroom posts, or 8-K news.
4
4
  allowed-tools: Bash(invd *)
5
5
  ---
6
6
 
@@ -38,6 +38,7 @@ Use the connected Invinite Data API MCP tools when available. Fall back to the `
38
38
  | Company IR documents (annual reports, proxy, ESG, investor-day decks, letters, webcast pages) | `earnings_company_documents`, `earnings_company_document` | `invd earnings company-documents\|document` |
39
39
  | Search company documents (passages with page numbers) | `earnings_document_search` | `invd earnings document-search` |
40
40
  | Keyword / guidance alerts | `earnings_call_alert_create\|list\|update\|delete\|test\|deliveries` | `invd webhooks …` |
41
+ | News (SEC filings and the companies' own newsrooms; full text with attribution), its text in blocks, AI-read developments | `news_list`, `news_item`, `news_text`, `news_developments`, `news_search` | `invd news list\|get\|text\|developments\|search` (`news asset-download` is CLI-only) |
41
42
 
42
43
  The discovery rules below apply to both transports: call `list_available_metrics` before ratios, growth, CAGR, or financial-statement analysis, and call `list_available_section_ids` before requesting filing sections.
43
44
 
@@ -146,6 +147,22 @@ invd webhooks update --id <id> --body '{"keywords":["tariffs","buyback"]}' --jso
146
147
  invd webhooks deliveries --id <id> --json
147
148
  ```
148
149
 
150
+ ### News
151
+
152
+ `invd news list` (FREE) lists items newest first from SEC EDGAR filings (`rights: public_record`) and the companies' own newsrooms (`rights: issuer`); wire services are never a source. `--ticker` / `--cik` = items that MENTION the company; `--publisher <cik>` = items the company PUBLISHED itself (its verified newsroom publication) — "what did NVIDIA announce" is `--publisher 1045810`, not `--ticker NVDA`. `--publication-type`, `--issuer-category` and `--issuer-tag` narrow the publisher's own publications (the last two need exactly one `--publisher`). The default window is the last 7 days (`--from` / `--to`, ≤ 92 days). Pages use a cursor, not an offset: `--all` follows `next_url`; by hand pass `next_cursor` as `--cursor` with the same filters.
153
+
154
+ - **Attribution duty.** Every item carries `attribution` (`publisher`, `source_url`, `published_at`, `edgar.form` + `edgar.accession` for a filing, `statement`). Whenever you quote or show a headline, lede, `body_text` or text block, name the publisher, link `source_url` and give the date (and the form + accession of a filing). The text is the publisher's own words: quote it verbatim, never present it as Invinite's or as verified fact.
155
+ - **Model use.** Process text with an AI model (summaries, extraction) only when the answer's `model_processing_allowed` is `true`; otherwise use the headline, links and attribution only. The MCP tools already withhold the words in that case (`text_withheld`).
156
+ - `invd news get --id <id>` (STANDARD) has `body_text` (`content_status: available`, else `no_text` = headline and link only), `sightings`, `companies`, images / files and up to 20 developments; `invd news text --id <id>` serves the text in citable blocks (a `409 revision_changed` means the item was corrected: restart without `--cursor`). `superseded_by` names a corrected successor.
157
+ - `invd news developments` lists product launches, partnerships, contracts, availability (AI-read from the text, `derived: true`): report `claim_status` as stated (`planned` is a plan, not availability) and cite the `evidence` quotes with the item's attribution.
158
+ - `invd news search -q <keywords>` searches headlines and texts (`-m lexical` keywords, the default; `-m literal` exact characters; `--field title|body|any`; default window 365 days, at most 8 passages). It answers `503 search_disabled` until the API enables it; read `coverage` before concluding from few or no hits, and cite each passage with its item's `attribution`.
159
+ - `invd news asset-download --id <id> --asset-id <asset_id>` returns a URL valid ≤ 60 s (keep the `credit` with the image); never store it.
160
+ - New items as they appear: `invd ws listen --news --tickers NVDA` (STANDARD); a webhook: `"events":["news.published"]` in `invd webhooks create --body` (STANDARD and above, filtered by `ciks`).
161
+
162
+ ```bash
163
+ invd webhooks create --body '{"url":"https://hooks.example.com/news","events":["news.published"],"filters":{"ciks":["1045810"]}}' --json
164
+ ```
165
+
149
166
  ## Commands Reference
150
167
 
151
168
  One example per command. `<name>` is a value to fill in; `invd <group> <action> --help` lists every flag. A command about one call also needs the selector described under *Earnings calls* (`--event-id`, or `-i` with `--year` + `--quarter` or `--date`).
@@ -215,7 +232,7 @@ invd earnings events -i MSFT --json
215
232
  invd earnings extractions --event-id cfbcf4f8-6d4d-41ef-9197-1c91ff2aef8c --json
216
233
 
217
234
  # Guidance history (optional: --period-kind, --basis, --limit)
218
- invd earnings guidance-history -i MSFT --metric revenue --json
235
+ invd earnings guidance-history -i MSFT --metric revenue_growth --json
219
236
 
220
237
  # Live earnings calls
221
238
  invd earnings live --json
@@ -491,6 +508,30 @@ invd metrics growth -i AAPL -p annual --json
491
508
  invd metrics ratios -i AAPL -p annual --json
492
509
  ```
493
510
 
511
+ ### news
512
+
513
+ News of US companies from SEC filings and their own newsrooms: items, full text with attribution, developments and files
514
+
515
+ ```bash
516
+ # Get a short-lived URL of a news image or file
517
+ invd news asset-download --id 4c1d9e62-3b7a-4f2e-8d1c-9e0a7b6c5d4f --asset-id 7e2f0c19-5a8b-4d3e-9f1a-2b6c8d0e4a7b --json
518
+
519
+ # List company developments from news (optional: --publisher, --topic, --item-id, --from, --to, --effective-from, --effective-to, --limit, --cursor, --all)
520
+ invd news developments --json
521
+
522
+ # Get a news item
523
+ invd news get --id 4c1d9e62-3b7a-4f2e-8d1c-9e0a7b6c5d4f --json
524
+
525
+ # List news items (optional: --ticker, --cik, --from, --to, --source, --kind, --topic, --earnings, --publisher, --publication-type, --issuer-category, --issuer-tag, --limit, --cursor, --all)
526
+ invd news list --json
527
+
528
+ # Search news (optional: --mode, --case-sensitive, --field, --ticker, --cik, --publisher, --kind, --topic, --from, --to, --limit)
529
+ invd news search -q "data center revenue" -m lexical -t NVDA --json
530
+
531
+ # Get a news item's text in blocks (optional: --limit, --max-chars, --cursor, --all)
532
+ invd news text --id 4c1d9e62-3b7a-4f2e-8d1c-9e0a7b6c5d4f --json
533
+ ```
534
+
494
535
  ### ownership
495
536
 
496
537
  13F holdings, holders and position changes of institutional investors
@@ -595,6 +636,11 @@ invd ws listen --earnings <event_id> --prices --json | jq 'select(.type=="price_
595
636
  # Keyword alerts on a live call, or across every live call (--all-live needs --keywords)
596
637
  invd ws listen --earnings 320193 --keywords tariffs,china --keyword-match stem --json
597
638
  invd ws listen --all-live --keywords tariffs --json
639
+
640
+ # New news items as they are published (STANDARD): one line each, NDJSON with --json
641
+ invd ws listen --news --tickers NVDA
642
+ invd ws listen --news --ciks 1045810 --news-sources ir --json
643
+ invd ws listen --news --earnings-news --news-kinds earnings_results,guidance --json
598
644
  ```
599
645
  <!-- /invd:hand:ws -->
600
646
 
@@ -644,6 +690,16 @@ invd earnings price-attribution --event-id <event_id> --json # optional: price
644
690
  ```
645
691
  `price-attribution` (MCP `earnings_call_price_moves`, STANDARD, 1 credit) lines up minute returns with what was said in that minute: temporal coincidence, not attribution of cause; pre-market bars are sparse, and a `404 price_attribution_unavailable` means the call is not attributed yet.
646
692
 
693
+ ### What did NVIDIA announce today
694
+ Ask for the company's own publications (publisher = CIK), then read one in full and cite it:
695
+ ```bash
696
+ invd news list --publisher 1045810 --from 2026-10-29 --json # what NVIDIA published itself
697
+ invd news list --ticker NVDA --source edgar --from 2026-10-29 --json # SEC filings mentioning NVIDIA
698
+ invd news get --id <id> --json # body_text + attribution
699
+ invd news developments --publisher 1045810 --topic product_launch --json
700
+ ```
701
+ Answer with the publisher, the date and the link of each item (`attribution`), and keep "announced" / "planned" claims as such.
702
+
647
703
  ### Reading specific filing sections
648
704
  First find section IDs, then fetch the section:
649
705
  ```bash
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Pure pieces of `invd ws listen --news`: the subscribe frame, the option parsers and one step per server frame of
3
+ * IDA's `news.live` channel (`src/routes/websocket/types/newsMessages.ts`). Every news frame carries
4
+ * `channel: "news.live"` — that, not its `type`, tells it apart from the earnings frames (both have `error` /
5
+ * `subscribed` / `unsubscribed`). A `news_item` frame's `item` is the same object as a `GET /v1/news` row.
6
+ */
7
+ export declare const NEWS_LIVE_CHANNEL = "news.live";
8
+ /** IDA `NEWS_KINDS` (`src/lib/news/constants.ts`) — change both or neither. */
9
+ export declare const NEWS_KINDS: readonly ["earnings_results", "results_date", "call_announcement", "event_announcement", "guidance", "m_and_a", "material_agreement", "management_change", "dividend", "capital_markets", "legal_spam", "promo", "other"];
10
+ /** IDA `NEWS_SOURCE_FILTERS`: the item's first source, SEC EDGAR or a company newsroom. */
11
+ export declare const NEWS_SOURCES: readonly ["edgar", "ir"];
12
+ export interface NewsListenOptions {
13
+ tickers?: string[];
14
+ ciks?: string[];
15
+ kinds?: string[];
16
+ sources?: string[];
17
+ earningsOnly: boolean;
18
+ /** NDJSON: every news frame as one line, nothing else on stdout. */
19
+ json: boolean;
20
+ }
21
+ /** The pushed item's fields `ws listen` prints (the full row is in `--json`). */
22
+ export interface NewsItemRow {
23
+ id: string;
24
+ title: string;
25
+ url: string;
26
+ published_at: string;
27
+ symbols: string[];
28
+ source: {
29
+ id: string;
30
+ };
31
+ is_earnings_news?: boolean;
32
+ attribution?: {
33
+ publisher?: string;
34
+ };
35
+ }
36
+ /** `--tickers`: 1–50 tickers (letters, digits, `.` and `-`; `BRK.B` and `BRK-B` both match). */
37
+ export declare function parseTickers(value: string | undefined): string[] | undefined;
38
+ /** `--ciks`: 1–50 CIKs (digits, padded or not). */
39
+ export declare function parseCiks(value: string | undefined): string[] | undefined;
40
+ export declare const parseNewsKinds: (value: string | undefined) => string[] | undefined;
41
+ export declare const parseNewsSources: (value: string | undefined) => string[] | undefined;
42
+ /** The `news.live` subscribe frame; an absent filter is left out (no filter = every new item). */
43
+ export declare function newsSubscribeFrame(opts: NewsListenOptions): {
44
+ sources?: string[] | undefined;
45
+ kinds?: string[] | undefined;
46
+ earnings_only?: boolean | undefined;
47
+ ciks?: string[] | undefined;
48
+ tickers?: string[] | undefined;
49
+ type: string;
50
+ channel: string;
51
+ };
52
+ /** A frame of the news channel (the socket also carries `new_filing` broadcasts, pings and earnings frames). */
53
+ export declare function isNewsFrame(frame: Record<string, any>): boolean;
54
+ /**
55
+ * One line per item: `2026-10-29 13:03:22Z nvidianews.nvidia.com NVDA NVIDIA Announces Rubin <url>` — time,
56
+ * source, tickers, headline, the original link (the headline is the publisher's, so its source travels with it).
57
+ */
58
+ export declare function formatNewsItem(item: NewsItemRow): string;
59
+ export interface NewsStep {
60
+ lines: string[];
61
+ /** Stop: exit code + a closing line. */
62
+ end?: {
63
+ code: 0 | 1;
64
+ message: string;
65
+ };
66
+ /** Close the socket and resubscribe through the backoff (`unavailable`). */
67
+ reconnect?: boolean;
68
+ }
69
+ /** One news frame → what to print / do. Unknown frames are ignored. */
70
+ export declare function newsStep(frame: Record<string, any>): NewsStep;
@@ -0,0 +1,120 @@
1
+ import chalk from 'chalk';
2
+ /**
3
+ * Pure pieces of `invd ws listen --news`: the subscribe frame, the option parsers and one step per server frame of
4
+ * IDA's `news.live` channel (`src/routes/websocket/types/newsMessages.ts`). Every news frame carries
5
+ * `channel: "news.live"` — that, not its `type`, tells it apart from the earnings frames (both have `error` /
6
+ * `subscribed` / `unsubscribed`). A `news_item` frame's `item` is the same object as a `GET /v1/news` row.
7
+ */
8
+ export const NEWS_LIVE_CHANNEL = 'news.live';
9
+ /** IDA `NEWS_KINDS` (`src/lib/news/constants.ts`) — change both or neither. */
10
+ export const NEWS_KINDS = [
11
+ 'earnings_results', 'results_date', 'call_announcement', 'event_announcement', 'guidance', 'm_and_a',
12
+ 'material_agreement', 'management_change', 'dividend', 'capital_markets', 'legal_spam', 'promo', 'other',
13
+ ];
14
+ /** IDA `NEWS_SOURCE_FILTERS`: the item's first source, SEC EDGAR or a company newsroom. */
15
+ export const NEWS_SOURCES = ['edgar', 'ir'];
16
+ /** IDA `NEWS_WS_MAX_IDENTIFIERS`: tickers / CIKs one subscription may name. */
17
+ const MAX_IDENTIFIERS = 50;
18
+ const list = (value) => [...new Set((value ?? '').split(',').map(v => v.trim()).filter(Boolean))];
19
+ /** `--tickers`: 1–50 tickers (letters, digits, `.` and `-`; `BRK.B` and `BRK-B` both match). */
20
+ export function parseTickers(value) {
21
+ if (value === undefined)
22
+ return undefined;
23
+ const tickers = list(value).map(t => t.toUpperCase());
24
+ if (tickers.length === 0 || tickers.length > MAX_IDENTIFIERS)
25
+ throw new Error(`--tickers takes 1–${MAX_IDENTIFIERS} comma-separated tickers`);
26
+ const bad = tickers.filter(t => !/^[A-Z0-9.-]{1,20}$/.test(t));
27
+ if (bad.length)
28
+ throw new Error(`--tickers: not a ticker: ${bad.join(', ')}`);
29
+ return tickers;
30
+ }
31
+ /** `--ciks`: 1–50 CIKs (digits, padded or not). */
32
+ export function parseCiks(value) {
33
+ if (value === undefined)
34
+ return undefined;
35
+ const ciks = list(value);
36
+ if (ciks.length === 0 || ciks.length > MAX_IDENTIFIERS)
37
+ throw new Error(`--ciks takes 1–${MAX_IDENTIFIERS} comma-separated CIKs`);
38
+ const bad = ciks.filter(c => !/^\d{1,10}$/.test(c));
39
+ if (bad.length)
40
+ throw new Error(`--ciks: not a CIK: ${bad.join(', ')}`);
41
+ return ciks;
42
+ }
43
+ function parseEnumList(flag, value, allowed) {
44
+ if (value === undefined)
45
+ return undefined;
46
+ const values = list(value);
47
+ const unknown = values.filter(v => !allowed.includes(v));
48
+ if (values.length === 0 || unknown.length) {
49
+ const named = unknown.length ? `Unknown value(s): ${unknown.join(', ')}. ` : '';
50
+ throw new Error(`${named}${flag} takes a comma-separated list of: ${allowed.join(', ')}`);
51
+ }
52
+ return values;
53
+ }
54
+ export const parseNewsKinds = (value) => parseEnumList('--news-kinds', value, NEWS_KINDS);
55
+ export const parseNewsSources = (value) => parseEnumList('--news-sources', value, NEWS_SOURCES);
56
+ /** The `news.live` subscribe frame; an absent filter is left out (no filter = every new item). */
57
+ export function newsSubscribeFrame(opts) {
58
+ return {
59
+ type: 'subscribe',
60
+ channel: NEWS_LIVE_CHANNEL,
61
+ ...(opts.tickers?.length ? { tickers: opts.tickers } : {}),
62
+ ...(opts.ciks?.length ? { ciks: opts.ciks } : {}),
63
+ ...(opts.earningsOnly ? { earnings_only: true } : {}),
64
+ ...(opts.kinds?.length ? { kinds: opts.kinds } : {}),
65
+ ...(opts.sources?.length ? { sources: opts.sources } : {}),
66
+ };
67
+ }
68
+ /** A frame of the news channel (the socket also carries `new_filing` broadcasts, pings and earnings frames). */
69
+ export function isNewsFrame(frame) {
70
+ return frame.channel === NEWS_LIVE_CHANNEL || frame.type === 'news_item';
71
+ }
72
+ /** `edgar` → `SEC EDGAR`, `ir:<host>` → the newsroom's host. */
73
+ function sourceName(id) {
74
+ if (id === 'edgar')
75
+ return 'SEC EDGAR';
76
+ return id.startsWith('ir:') ? id.slice(3) : id;
77
+ }
78
+ /**
79
+ * One line per item: `2026-10-29 13:03:22Z nvidianews.nvidia.com NVDA NVIDIA Announces Rubin <url>` — time,
80
+ * source, tickers, headline, the original link (the headline is the publisher's, so its source travels with it).
81
+ */
82
+ export function formatNewsItem(item) {
83
+ const at = item.published_at.replace('T', ' ').replace(/\.\d+Z$/, 'Z');
84
+ const tickers = item.symbols.length ? item.symbols.join(',') : '—';
85
+ const earnings = item.is_earnings_news ? ` ${chalk.yellow('[earnings]')}` : '';
86
+ return `${chalk.dim(at)} ${sourceName(item.source.id)} ${chalk.bold(tickers)} ${item.title}${earnings} ${chalk.dim(item.url)}`;
87
+ }
88
+ /** One news frame → what to print / do. Unknown frames are ignored. */
89
+ export function newsStep(frame) {
90
+ switch (frame.type) {
91
+ case 'subscribed': {
92
+ const f = frame.filters ?? {};
93
+ const scope = [
94
+ f.tickers?.length ? `tickers ${f.tickers.join(',')}` : null,
95
+ f.ciks?.length ? `CIKs ${f.ciks.join(',')}` : null,
96
+ f.kinds?.length ? `kinds ${f.kinds.join(',')}` : null,
97
+ f.sources?.length ? `sources ${f.sources.join(',')}` : null,
98
+ f.earnings_only ? 'earnings only' : null,
99
+ ].filter(Boolean);
100
+ return { lines: [chalk.bold(`news.live · ${scope.length ? scope.join(' · ') : 'every company'}`)] };
101
+ }
102
+ case 'news_item':
103
+ return { lines: frame.item ? [formatNewsItem(frame.item)] : [] };
104
+ case 'unsubscribed':
105
+ return { lines: [], end: { code: 0, message: 'news subscription ended' } };
106
+ case 'error': {
107
+ if (frame.code === 'unavailable')
108
+ return { lines: [chalk.dim(`unavailable: ${frame.message}; retrying`)], reconnect: true };
109
+ const message = frame.code === 'forbidden_tier'
110
+ ? `news.live needs the STANDARD plan (${frame.message})`
111
+ : frame.code === 'channel_unavailable'
112
+ ? `live news is not enabled on the API yet (${frame.message})`
113
+ : `${frame.code}: ${frame.message}`;
114
+ return { lines: [], end: { code: 1, message } };
115
+ }
116
+ default:
117
+ return { lines: [] };
118
+ }
119
+ }
120
+ //# sourceMappingURL=news-live.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"news-live.js","sourceRoot":"","sources":["../../../src/client/news-live.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type KeywordOptions, type LiveTarget } from './earnings-live.js';
2
+ import { type NewsListenOptions } from './news-live.js';
2
3
  export interface EarningsListenOptions {
3
4
  target: LiveTarget;
4
5
  sinceSeq: number;
@@ -11,6 +12,8 @@ export interface EarningsListenOptions {
11
12
  /** Keyword / guidance alerts on the subscription (required with the `all_live` target). */
12
13
  keywords?: KeywordOptions;
13
14
  }
15
+ /** `earnings` and `news` exclude each other (`ws listen` refuses both); neither = the filing stream. */
14
16
  export declare function connectWebSocket(opts?: {
15
17
  earnings?: EarningsListenOptions;
18
+ news?: NewsListenOptions;
16
19
  }): Promise<void>;
@@ -2,16 +2,20 @@ import { getApiKey } from '../config/auth.js';
2
2
  import { getBaseUrl } from '../config/config-manager.js';
3
3
  import chalk from 'chalk';
4
4
  import { initialLiveState, isAllLive, isEarningsFrame, liveStep, subscribeFrame, } from './earnings-live.js';
5
+ import { isNewsFrame, newsStep, newsSubscribeFrame } from './news-live.js';
5
6
  /** Close codes of `/v1/ws` that a reconnect cannot fix (bad key, plan, connection limit). */
6
7
  const PERMANENT_CLOSE_CODES = new Set([4001, 4003, 4029]);
7
8
  const CLEAR_LINE = '\r\x1b[2K';
9
+ /** `earnings` and `news` exclude each other (`ws listen` refuses both); neither = the filing stream. */
8
10
  export async function connectWebSocket(opts = {}) {
9
11
  const apiKey = await getApiKey();
10
12
  const base = getBaseUrl().replace(/\/+$/, '').replace(/^http/, 'ws');
11
13
  const url = `${base}/v1/ws?api_key=${encodeURIComponent(apiKey)}`;
12
14
  const earnings = opts.earnings;
15
+ const news = opts.news;
16
+ const ndjson = Boolean(earnings?.json || news?.json);
13
17
  const status = (line) => {
14
- if (!earnings?.json)
18
+ if (!ndjson)
15
19
  console.log(line);
16
20
  };
17
21
  let reconnectDelay = 1000;
@@ -67,6 +71,28 @@ export async function connectWebSocket(opts = {}) {
67
71
  ws.close();
68
72
  }
69
73
  }
74
+ function handleNews(ws, data) {
75
+ if (!news)
76
+ return;
77
+ if (news.json)
78
+ console.log(JSON.stringify(data));
79
+ const step = newsStep(data);
80
+ if (!news.json)
81
+ for (const line of step.lines)
82
+ console.log(line);
83
+ if (step.end) {
84
+ if (step.end.code === 0) {
85
+ status(chalk.dim(step.end.message));
86
+ finish();
87
+ }
88
+ else {
89
+ finish(new Error(step.end.message));
90
+ }
91
+ }
92
+ else if (step.reconnect) {
93
+ ws.close();
94
+ }
95
+ }
70
96
  function connect() {
71
97
  status(chalk.dim('Connecting to WebSocket...'));
72
98
  const ws = new WebSocket(url);
@@ -81,6 +107,11 @@ export async function connectWebSocket(opts = {}) {
81
107
  // A reconnect resumes after the last printed final (the API replays the gap).
82
108
  ws.send(JSON.stringify(subscribeFrame(earnings.target, live.lastSeq, earnings.partials, earnings.keywords, earnings.prices)));
83
109
  }
110
+ else if (news) {
111
+ status(chalk.green('Connected; subscribing to news.live'));
112
+ // Items published while disconnected are not replayed: `invd news list` has them.
113
+ ws.send(JSON.stringify(newsSubscribeFrame(news)));
114
+ }
84
115
  else {
85
116
  console.log(chalk.green('Connected to filing stream'));
86
117
  }
@@ -90,7 +121,12 @@ export async function connectWebSocket(opts = {}) {
90
121
  const data = JSON.parse(String(event.data));
91
122
  if (data.type === 'ping')
92
123
  return;
93
- if (earnings) {
124
+ if (news) {
125
+ // Only news frames: the filing broadcasts on the same socket are not what --news asked for.
126
+ if (isNewsFrame(data))
127
+ handleNews(ws, data);
128
+ }
129
+ else if (earnings) {
94
130
  handleEarnings(ws, data);
95
131
  }
96
132
  else if (data.type === 'new_filing') {
@@ -104,7 +140,7 @@ export async function connectWebSocket(opts = {}) {
104
140
  }
105
141
  }
106
142
  catch {
107
- if (!earnings)
143
+ if (!earnings && !news)
108
144
  console.log(String(event.data));
109
145
  }
110
146
  });
@@ -121,7 +157,7 @@ export async function connectWebSocket(opts = {}) {
121
157
  reconnectDelay = Math.min(reconnectDelay * 2, 30000);
122
158
  });
123
159
  ws.addEventListener('error', (error) => {
124
- if (!earnings?.json)
160
+ if (!ndjson)
125
161
  console.error(chalk.red('WebSocket error:'), error);
126
162
  });
127
163
  }
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-client.js","sourceRoot":"","sources":["../../../src/client/websocket-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"websocket-client.js","sourceRoot":"","sources":["../../../src/client/websocket-client.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { Command } from 'commander';
2
2
  import { type EarningsListenOptions } from '../client/websocket-client.js';
3
+ import { type NewsListenOptions } from '../client/news-live.js';
3
4
  export interface ListenOptions {
4
5
  earnings?: string;
5
6
  allLive?: boolean;
@@ -11,7 +12,18 @@ export interface ListenOptions {
11
12
  keywordMatch?: string;
12
13
  speakerRoles?: string;
13
14
  minRank?: string;
15
+ news?: boolean;
16
+ tickers?: string;
17
+ ciks?: string;
18
+ newsKinds?: string;
19
+ newsSources?: string;
20
+ earningsNews?: boolean;
14
21
  }
22
+ /**
23
+ * `ws listen` options → the `news.live` subscription, or null when `--news` is absent. Refused before connecting:
24
+ * `--news` with `--earnings` / `--all-live` or any live-call flag, and the news filters without `--news`.
25
+ */
26
+ export declare function buildNewsOptions(cmdOpts: ListenOptions, json: boolean): NewsListenOptions | null;
15
27
  /**
16
28
  * `ws listen` options → the earnings subscription, or null for the filing stream. Mirrors the
17
29
  * API's refusals client-side: the global scope needs keywords, the alert tuning needs keywords,