@aisa-one/cli 0.1.5 → 0.1.6

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
@@ -84,11 +84,12 @@ aisa scholar "transformer architecture" # academic papers
84
84
  ### Finance
85
85
 
86
86
  ```bash
87
+ aisa stock AAPL # summary: company info + estimates + news
87
88
  aisa stock AAPL --field insider # insider trades
88
89
  aisa stock AAPL --field news # company news
89
90
  aisa stock TSLA --field filings # SEC filings
90
- aisa stock AAPL --field price # stock price (⚠️ may return empty for some tickers)
91
- aisa stock MSFT --field earnings # earnings data (⚠️ limited ticker support)
91
+ aisa stock MSFT --field estimates # analyst EPS & revenue estimates
92
+ aisa stock AAPL --field financials # balance sheets, income statements
92
93
  aisa crypto BTC # crypto price snapshot
93
94
  aisa crypto ETH --period 30d # historical
94
95
  aisa screener --sector Technology # stock screener
@@ -215,7 +216,7 @@ The `domain: true` option in `RequestOptions` (see `src/api.ts`) selects which b
215
216
 
216
217
  **Models API follows OpenAI format.** The `/v1/models` endpoint returns `owned_by` (not `provider`) and has no `name`, `pricing`, or `contextWindow` fields.
217
218
 
218
- **Some financial endpoints return empty data.** `financial/prices` and `financial/financial-metrics/snapshot` may return `{}` for certain tickers. `financial/insider-trades`, `financial/news`, and `financial/filings` work reliably.
219
+ **Some financial endpoints return empty data.** `financial/prices` and `financial/financial-metrics/snapshot` return `{}` for all tickers (backend issue). The default `aisa stock` now fetches `company/facts` + `analyst-estimates` + `news` instead. Working fields: `info`, `estimates`, `financials`, `filings`, `insider`, `institutional`, `news`.
219
220
 
220
221
  ## License
221
222
 
@@ -1,40 +1,79 @@
1
1
  import ora from "ora";
2
+ import chalk from "chalk";
2
3
  import { requireApiKey } from "../config.js";
3
4
  import { apiRequest } from "../api.js";
4
5
  import { error, formatJson } from "../utils/display.js";
5
6
  const FIELD_ENDPOINTS = {
6
- price: "financial/prices",
7
- earnings: "financial/earnings/press-releases",
7
+ info: "financial/company/facts",
8
+ estimates: "financial/analyst-estimates",
8
9
  financials: "financial/financials",
9
10
  filings: "financial/filings",
10
11
  insider: "financial/insider-trades",
11
12
  institutional: "financial/institutional-ownership",
12
- metrics: "financial/financial-metrics/snapshot",
13
13
  news: "financial/news",
14
14
  };
15
15
  export async function stockAction(symbol, options) {
16
16
  const key = requireApiKey();
17
- const field = options.field || "price";
17
+ const field = options.field || "info";
18
+ const ticker = symbol.toUpperCase();
19
+ // Default: show a summary of company info + estimates + news
20
+ if (!options.field) {
21
+ const spinner = ora(`Fetching ${ticker}...`).start();
22
+ const [infoRes, estRes, newsRes] = await Promise.all([
23
+ apiRequest(key, "financial/company/facts", { query: { ticker }, domain: true }),
24
+ apiRequest(key, "financial/analyst-estimates", { query: { ticker }, domain: true }),
25
+ apiRequest(key, "financial/news", { query: { ticker, limit: "3" }, domain: true }),
26
+ ]);
27
+ spinner.stop();
28
+ if (options.raw) {
29
+ console.log(JSON.stringify({ info: infoRes.data, estimates: estRes.data, news: newsRes.data }));
30
+ return;
31
+ }
32
+ // Company info
33
+ const facts = infoRes.data?.company_facts;
34
+ if (facts) {
35
+ console.log(`\n ${chalk.cyan.bold(facts.name || ticker)} ${chalk.gray(`(${facts.ticker || ticker})`)}`);
36
+ const details = [facts.exchange, facts.sector, facts.industry].filter(Boolean).join(" · ");
37
+ if (details)
38
+ console.log(` ${chalk.gray(details)}`);
39
+ if (facts.location)
40
+ console.log(` ${chalk.gray(facts.location)}`);
41
+ }
42
+ else {
43
+ console.log(`\n ${chalk.cyan.bold(ticker)}`);
44
+ }
45
+ // Analyst estimates
46
+ const estimates = estRes.data?.analyst_estimates;
47
+ if (estimates && estimates.length > 0) {
48
+ console.log(`\n ${chalk.white.bold("Analyst Estimates")}`);
49
+ for (const e of estimates.slice(0, 3)) {
50
+ const period = e.fiscal_period?.split("T")[0] || e.period || "";
51
+ const eps = e.earnings_per_share != null ? `EPS $${e.earnings_per_share.toFixed(2)}` : "";
52
+ const rev = e.revenue != null ? `Rev $${(e.revenue / 1e9).toFixed(1)}B` : "";
53
+ console.log(` ${chalk.gray(period)} ${eps} ${rev}`);
54
+ }
55
+ }
56
+ // Latest news
57
+ const news = newsRes.data?.news;
58
+ if (news && news.length > 0) {
59
+ console.log(`\n ${chalk.white.bold("Latest News")}`);
60
+ for (const n of news) {
61
+ const date = n.date ? new Date(n.date).toLocaleDateString() : "";
62
+ console.log(` ${chalk.gray(date)} ${n.title}`);
63
+ }
64
+ }
65
+ console.log();
66
+ return;
67
+ }
68
+ // Specific field
18
69
  const endpoint = FIELD_ENDPOINTS[field];
19
70
  if (!endpoint) {
20
71
  error(`Unknown field: ${field}. Valid: ${Object.keys(FIELD_ENDPOINTS).join(", ")}`);
21
72
  return;
22
73
  }
23
- const spinner = ora(`Fetching ${field} for ${symbol.toUpperCase()}...`).start();
24
- const query = { ticker: symbol.toUpperCase() };
25
- // Price endpoint needs additional params for sensible defaults
26
- if (field === "price") {
27
- const end = new Date();
28
- const start = new Date();
29
- start.setDate(start.getDate() - 30);
30
- query.interval = "day";
31
- query.interval_multiplier = "1";
32
- query.start_date = start.toISOString().split("T")[0];
33
- query.end_date = end.toISOString().split("T")[0];
34
- query.limit = "30";
35
- }
74
+ const spinner = ora(`Fetching ${field} for ${ticker}...`).start();
36
75
  const res = await apiRequest(key, endpoint, {
37
- query,
76
+ query: { ticker },
38
77
  domain: true,
39
78
  });
40
79
  if (!res.success) {
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "0.1.5";
1
+ export declare const VERSION = "0.1.6";
2
2
  export declare const BASE_URL = "https://api.aisa.one";
3
3
  export declare const CLI_BASE_URL = "https://api.aisa.one/v1";
4
4
  export declare const APIS_BASE_URL = "https://api.aisa.one/apis/v1";
package/dist/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = "0.1.5";
1
+ export const VERSION = "0.1.6";
2
2
  export const BASE_URL = "https://api.aisa.one";
3
3
  export const CLI_BASE_URL = `${BASE_URL}/v1`;
4
4
  export const APIS_BASE_URL = `${BASE_URL}/apis/v1`;
package/dist/index.js CHANGED
@@ -143,7 +143,7 @@ program
143
143
  program
144
144
  .command("stock <symbol>")
145
145
  .description("Look up stock data")
146
- .option("--field <field>", "Data field: price, earnings, financials, filings, insider, institutional, metrics, news", "price")
146
+ .option("--field <field>", "Data field: info, estimates, financials, filings, insider, institutional, news")
147
147
  .option("--raw", "Raw JSON output")
148
148
  .action(wrap(stockAction));
149
149
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aisa-one/cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "CLI for the AISA unified AI infrastructure platform - access 70+ LLMs, web search, finance, Twitter, and video generation APIs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",