@invinite-org/invinite-data-cli 0.1.20 → 0.1.22

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
@@ -30,11 +30,33 @@ Requires Node.js >= 20.
30
30
 
31
31
  ## Authentication
32
32
 
33
- The CLI requires an Invinite Data API key. The key is resolved in the following order:
33
+ The recommended way to authenticate is browser login:
34
+
35
+ ```bash
36
+ invd login
37
+ ```
38
+
39
+ The browser flow creates a revocable, 90-day Data API key and stores it in the
40
+ OS keychain when available (with local CLI config as a fallback). The sign-in
41
+ also appears in the web UI's Data API key settings. If you belong to multiple
42
+ teams, choose one explicitly:
43
+
44
+ ```bash
45
+ invd login --team <teamId>
46
+ ```
47
+
48
+ To revoke the browser sign-in and remove the locally stored credential:
49
+
50
+ ```bash
51
+ invd logout
52
+ ```
53
+
54
+ Manual API keys remain supported. The active key is resolved in the following order:
34
55
 
35
56
  1. **Environment variable** — `INVINITE_DATA_API_KEY`
36
- 2. **OS keychain** — via the optional `keytar` package
37
- 3. **Stored config** — set with the CLI
57
+ 2. **Current directory `.env` file** — `INVINITE_DATA_API_KEY=...`
58
+ 3. **OS keychain** — via the optional `keytar` package
59
+ 4. **Stored config** — set with the CLI
38
60
 
39
61
  ### Set your API key
40
62
 
@@ -48,10 +70,21 @@ You'll be prompted to enter your key (input is masked). Alternatively, export it
48
70
  export INVINITE_DATA_API_KEY=your-api-key
49
71
  ```
50
72
 
73
+ Because environment and `.env` values take precedence over stored credentials,
74
+ `invd logout` will tell you to remove them manually when either is active.
75
+
51
76
  ## AI Plugin
52
77
 
53
78
  This repo includes plugins for AI coding tools that enable AI-powered financial data retrieval and analysis. Supports **Claude Code**, **OpenCode**, **Codex**, and **Copilot**.
54
79
 
80
+ ### Choose an integration
81
+
82
+ - **Standalone skill:** installs the Invinite workflow and CLI reference. It prefers MCP when connected and falls back to the local `invd` CLI.
83
+ - **Standalone MCP connector:** add `https://data.invinite.com/t/<teamId>/mcp` in Claude's connector settings, leave OAuth client ID/secret empty, and complete browser OAuth. This supplies tools but not the packaged research workflows.
84
+ - **Claude plugin:** bundles the skill, remote MCP connector, data agent, and research commands. During setup, enter the team ID shown in the team-pinned MCP URL in Invinite Data API settings; OAuth still uses Dynamic Client Registration and PKCE.
85
+
86
+ The team ID controls access, usage, and billing for MCP calls. CLI calls use the team selected by `invd login --team <teamId>` and do not inherit the plugin's connector setting.
87
+
55
88
  ### Quick install
56
89
 
57
90
  ```bash
@@ -98,6 +131,8 @@ npx @invinite-org/invinite-data-cli@latest plugin uninstall --all --global
98
131
  claude --plugin-dir /path/to/invinite-data-cli/claude-plugin
99
132
  ```
100
133
 
134
+ The Claude plugin also includes `compare-companies`, `analyze-filing`, and `ownership-review`. Its `.mcp.json` connects the team-pinned remote server automatically; use `/mcp` to complete OAuth or inspect connection status in Claude Code. In Claude web/Desktop, install the plugin through your organization's plugin marketplace, enter the team ID when prompted, and connect the bundled connector.
135
+
101
136
  ### Usage examples
102
137
 
103
138
  Use `/financial-research` for multi-step analysis:
@@ -123,6 +158,8 @@ These options are available on all data commands:
123
158
 
124
159
  ## Commands
125
160
 
161
+ - `login` — Log in through your browser (`--team <teamId>` for multi-team users)
162
+ - `logout` — Revoke the current browser sign-in and clear local credentials
126
163
  - [config](#config) — Manage CLI configuration
127
164
  - [health](#health) — Check API health
128
165
  - [company](#company) — Company information
@@ -1,11 +1,19 @@
1
1
  {
2
- "name": "invd",
2
+ "name": "invinite-financial-data",
3
3
  "description": "Fetch and analyze financial data using the Invinite Data API — company fundamentals, financial statements, SEC filings, institutional ownership, insider trades, and more.",
4
- "version": "0.1.0",
4
+ "version": "0.3.0",
5
5
  "author": {
6
- "name": "Outraday"
6
+ "name": "Invinite"
7
7
  },
8
8
  "homepage": "https://github.com/outraday-org/invinite-data-cli",
9
9
  "repository": "https://github.com/outraday-org/invinite-data-cli",
10
- "license": "ISC"
10
+ "license": "ISC",
11
+ "userConfig": {
12
+ "team_id": {
13
+ "type": "string",
14
+ "title": "Invinite team ID",
15
+ "description": "Team billed for Data API usage. Copy it from the team-pinned MCP URL in Invinite Data API settings.",
16
+ "required": true
17
+ }
18
+ }
11
19
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "invinite-financial-data": {
4
+ "type": "http",
5
+ "url": "https://data.invinite.com/t/${user_config.team_id}/mcp"
6
+ }
7
+ }
8
+ }
@@ -23,7 +23,7 @@ You are a financial data retrieval specialist. Your job is to fetch the requeste
23
23
  - Always use `--json` on every data command
24
24
  - **Before querying metrics (ratios, CAGR, or growth) or financial statements, first run `invd metadata metrics --json`** to discover the available metric identifiers. The responses from these endpoints use `metric_id` keys — you need the metadata to know what metrics exist and to correctly interpret the results. Run this as a first step alongside or before your main data queries.
25
25
  - **Before querying filing sections, first run `invd metadata section-ids --json`** to discover valid section IDs.
26
- - If a command fails with an authentication error, report it clearly and tell the caller that `INVINITE_DATA_API_KEY` must be set or `invd config set-key` must be run
26
+ - If a command fails with an authentication error, report it clearly and tell the caller to run `invd login`; `INVINITE_DATA_API_KEY` and `invd config set-key` remain manual fallbacks
27
27
  - If a company identifier is ambiguous, use `invd company search -q "<name>" --json` first to resolve it
28
28
  - For comparing companies, prefer `invd financials snapshot -i AAPL,MSFT,GOOGL -p annual --json` over individual queries
29
29
  - When fetching financial statements, default to `annual` period unless the request specifies otherwise
@@ -0,0 +1,15 @@
1
+ ---
2
+ description: Analyze a company's SEC filing for material changes, risks, management commentary, and evidence.
3
+ argument-hint: <ticker> [form type or research question]
4
+ ---
5
+
6
+ # Analyze SEC Filing
7
+
8
+ Analyze the filing requested in `$ARGUMENTS` using Invinite Data.
9
+
10
+ 1. Resolve the company and identify the relevant filing and accession number.
11
+ 2. Discover valid filing section IDs before requesting sections.
12
+ 3. Retrieve only the sections needed for the question, normally risk factors, MD&A, business, and financial statements.
13
+ 4. Separate direct filing evidence from your interpretation.
14
+ 5. Report the form type, filing date, accession number, and section for every material finding.
15
+ 6. Flag missing sections or unavailable periods instead of inferring their contents.
@@ -0,0 +1,15 @@
1
+ ---
2
+ description: Compare the financial performance, valuation, growth, and risks of two or more companies.
3
+ argument-hint: <tickers or company names> [focus]
4
+ ---
5
+
6
+ # Compare Companies
7
+
8
+ Compare the companies in `$ARGUMENTS` using Invinite Data.
9
+
10
+ 1. Resolve ambiguous company names with `company_search` or the equivalent `invd` command.
11
+ 2. Fetch available metric definitions before requesting financial metrics.
12
+ 3. Fetch company details, the latest annual standardized snapshot, profitability and valuation ratios, and five-year CAGR where available.
13
+ 4. Run independent reads in parallel when the active Claude surface supports it.
14
+ 5. Present a compact comparison table followed by the most material strengths, weaknesses, and data limitations.
15
+ 6. Cite the reporting periods used; do not mix annual and quarterly values without labeling them.
@@ -0,0 +1,14 @@
1
+ ---
2
+ description: Review institutional ownership, position changes, concentration, and insider trading for a company.
3
+ argument-hint: <ticker> [period or focus]
4
+ ---
5
+
6
+ # Review Ownership
7
+
8
+ Review ownership activity for `$ARGUMENTS` using Invinite Data.
9
+
10
+ 1. Resolve the company identifier.
11
+ 2. Fetch institutional holdings, institutional transactions, and insider trades for the requested period.
12
+ 3. Identify the largest holders, notable new or exited positions, and meaningful insider acquisitions or dispositions.
13
+ 4. Distinguish position value from share count and filing date from transaction date.
14
+ 5. Present concise tables and call out reporting-lag limitations in institutional filings.
@@ -1,21 +1,51 @@
1
1
  ---
2
- name: invinite-data-cli
3
- description: Fetch financial data using the Invinite Data API CLI. Use this skill whenever the user wants to look up company information, financial statements, SEC filings, institutional ownership, insider trades, IPO data, market holidays, financial metrics, or any stock/company-related data. Also use when the user mentions tickers, CIKs, balance sheets, income statements, cash flows, 10-K, 10-Q, ratios, CAGR, growth rates, dividends, stock splits, or institutional holdings — even if they don't mention "Invinite" by name.
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, 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, or institutional holdings.
4
4
  allowed-tools: Bash(invd *)
5
5
  ---
6
6
 
7
- # Invinite Data API CLI
7
+ # Invinite Data API
8
8
 
9
- The `invd` CLI provides access to comprehensive financial data from the Invinite Data API. Always use `--json` when fetching data for analysis — it returns structured JSON you can pipe to `jq` or parse programmatically.
9
+ Use the connected Invinite Data API MCP tools when available. Fall back to the `invd` CLI when MCP is unavailable. Both transports access the same team-billed Data API.
10
+
11
+ ## Transport selection
12
+
13
+ 1. Prefer MCP tools when an Invinite Data connector is available. Call the direct domain tool matching the request; unlike the Web API MCP server, the Data API MCP server does not use meta-tools such as `call_endpoint`.
14
+ 2. Use the CLI examples below when MCP is unavailable or when the user explicitly requests CLI usage. Always pass `--json` for data used in analysis.
15
+ 3. Do not mix transports merely to repeat a successful request.
16
+
17
+ ### MCP and CLI mapping
18
+
19
+ | Data need | MCP tool | CLI command family |
20
+ |---|---|---|
21
+ | Search/details/list | `company_search`, `company_details`, `available_companies` | `invd company ...` |
22
+ | Dividends/periods/splits | `company_dividends`, `company_fiscal_periods`, `company_splits` | `invd company ...` |
23
+ | Standardized statements/snapshots | `standardized_financial_statement`, `standardized_financial_snapshot` | `invd financials ...` |
24
+ | As-reported statements/snapshots | `as_reported_financial_statement`, `as_reported_financial_snapshot` | `invd financials ... --as-reported` |
25
+ | Ratios/growth/CAGR | `financial_ratios`, `financial_growth`, `financial_cagr` | `invd metrics ...` |
26
+ | Segment data | `segmented_financials` | `invd segments ...` |
27
+ | SEC filings/search/sections | `sec_filings`, `sec_filings_search`, `sec_filing_sections` | `invd filings ...` |
28
+ | Filing and metric discovery | `sec_available_form_types`, `list_available_section_ids`, `list_available_metrics` | `invd filings form-types`, `invd metadata ...` |
29
+ | Institutional ownership | `holdings_by_company`, `holdings_by_investor`, `institutional_investors`, `institutional_transactions` | `invd ownership ...` |
30
+ | Insider trades/IPOs/holidays | `insider_trades`, `ipos`, `market_holidays` | `invd insider-trades`, `invd ipos`, `invd market ...` |
31
+
32
+ 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.
10
33
 
11
34
  ## Prerequisites
12
35
 
13
- The CLI must be installed (`npm install -g @invinite-org/invinite-data-cli`) and authenticated. Authentication is resolved in this order:
36
+ ### MCP
37
+
38
+ Connect `https://data.invinite.com/t/<teamId>/mcp` through OAuth. The team in the URL controls data billing. Leave OAuth client ID and secret empty so the client uses Dynamic Client Registration and PKCE.
39
+
40
+ ### CLI
41
+
42
+ Install the CLI with `npm install -g @invinite-org/invinite-data-cli`, then run `invd login` or `invd login --team <teamId>`. Authentication is resolved in this order:
14
43
  1. `INVINITE_DATA_API_KEY` environment variable
15
- 2. OS keychain (via optional `keytar`)
16
- 3. Stored config (set via `invd config set-key`)
44
+ 2. `.env` file
45
+ 3. OS keychain (via optional `keytar`)
46
+ 4. Stored config
17
47
 
18
- If a command fails with an auth error, tell the user to run `invd config set-key` or set `INVINITE_DATA_API_KEY`.
48
+ If an MCP call fails with an auth error, reconnect the connector and complete OAuth. If a CLI call fails with an auth error, run `invd login`; manual `invd config set-key` and `INVINITE_DATA_API_KEY` remain supported fallbacks.
19
49
 
20
50
  ## Global Options
21
51
 
package/dist/src/cli.js CHANGED
@@ -14,6 +14,7 @@ import { registerMarketCommands } from './commands/market.js';
14
14
  import { registerMetadataCommands } from './commands/metadata.js';
15
15
  import { registerWsCommands } from './commands/ws.js';
16
16
  import { registerPluginCommands } from './commands/plugin.js';
17
+ import { registerLoginCommands } from './commands/login.js';
17
18
  export function createProgram() {
18
19
  const program = new Command();
19
20
  program
@@ -42,6 +43,7 @@ export function createProgram() {
42
43
  registerMetadataCommands(program);
43
44
  registerWsCommands(program);
44
45
  registerPluginCommands(program);
46
+ registerLoginCommands(program);
45
47
  return program;
46
48
  }
47
49
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,yCAAyC,CAAC;SACtD,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;SACnD,MAAM,CAAC,OAAO,EAAE,mCAAmC,CAAC;SACpD,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,WAAW,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACpC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,yBAAyB,CAAC,OAAO,CAAC,CAAC;IACnC,6BAA6B,CAAC,OAAO,CAAC,CAAC;IACvC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAEhC,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,yCAAyC,CAAC;SACtD,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;SACnD,MAAM,CAAC,OAAO,EAAE,mCAAmC,CAAC;SACpD,IAAI,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,WAAW,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACpC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,yBAAyB,CAAC,OAAO,CAAC,CAAC;IACnC,6BAA6B,CAAC,OAAO,CAAC,CAAC;IACvC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Command } from 'commander';
2
+ type ExchangeData = {
3
+ key: string;
4
+ keyHint: string;
5
+ teamId: string;
6
+ label: string;
7
+ };
8
+ export type LoginDependencies = {
9
+ fetch: typeof fetch;
10
+ openBrowser: (url: string) => Promise<void>;
11
+ timeoutMs: number;
12
+ };
13
+ export declare function login(options?: {
14
+ team?: string;
15
+ }, dependencies?: LoginDependencies): Promise<ExchangeData>;
16
+ export declare function logout(dependencies?: Pick<LoginDependencies, 'fetch'>): Promise<void>;
17
+ export declare function registerLoginCommands(program: Command): void;
18
+ export {};
@@ -0,0 +1,252 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { createServer } from 'node:http';
3
+ import { hostname } from 'node:os';
4
+ import { spawn } from 'node:child_process';
5
+ import chalk from 'chalk';
6
+ import { clearApiKey, resolveApiKey, setApiKey } from '../config/auth.js';
7
+ import { getBaseUrl } from '../config/config-manager.js';
8
+ const CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
9
+ const KEY_LIFETIME_MS = 90 * 24 * 60 * 60 * 1000;
10
+ const MAX_BIND_ATTEMPTS = 3;
11
+ const defaultDependencies = {
12
+ fetch: globalThis.fetch,
13
+ openBrowser,
14
+ timeoutMs: CALLBACK_TIMEOUT_MS,
15
+ };
16
+ function errorMessage(error) {
17
+ return error instanceof Error ? error.message : String(error);
18
+ }
19
+ async function parseEnvelope(response) {
20
+ try {
21
+ return await response.json();
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ }
27
+ function browserCommand(url) {
28
+ if (process.platform === 'darwin')
29
+ return { command: 'open', args: [url] };
30
+ if (process.platform === 'win32')
31
+ return { command: 'cmd', args: ['/c', 'start', '', url] };
32
+ return { command: 'xdg-open', args: [url] };
33
+ }
34
+ async function openBrowser(url) {
35
+ const target = browserCommand(url);
36
+ await new Promise((resolve, reject) => {
37
+ const child = spawn(target.command, target.args, { detached: true, stdio: 'ignore' });
38
+ child.once('error', reject);
39
+ child.once('spawn', () => {
40
+ child.unref();
41
+ resolve();
42
+ });
43
+ });
44
+ }
45
+ function callbackHtml(title, message) {
46
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>${title}</title></head><body><main><h1>${title}</h1><p>${message}</p></main></body></html>`;
47
+ }
48
+ async function closeServer(server) {
49
+ if (!server.listening)
50
+ return;
51
+ await new Promise((resolve) => server.close(() => resolve()));
52
+ }
53
+ async function listenOnRandomPort(server) {
54
+ for (let attempt = 0; attempt < MAX_BIND_ATTEMPTS; attempt += 1) {
55
+ const port = 49_152 + randomBytes(2).readUInt16BE(0) % (65_535 - 49_152 + 1);
56
+ try {
57
+ await new Promise((resolve, reject) => {
58
+ const handleError = (error) => reject(error);
59
+ server.once('error', handleError);
60
+ server.listen(port, '127.0.0.1', () => {
61
+ server.off('error', handleError);
62
+ resolve();
63
+ });
64
+ });
65
+ return port;
66
+ }
67
+ catch (error) {
68
+ if (error.code !== 'EADDRINUSE' || attempt === MAX_BIND_ATTEMPTS - 1)
69
+ throw error;
70
+ }
71
+ }
72
+ throw new Error('Could not start the login callback server');
73
+ }
74
+ export async function login(options = {}, dependencies = defaultDependencies) {
75
+ const state = randomBytes(16).toString('hex');
76
+ let resolveCallback = () => undefined;
77
+ let rejectCallback = () => undefined;
78
+ const callback = new Promise((resolve, reject) => {
79
+ resolveCallback = resolve;
80
+ rejectCallback = reject;
81
+ });
82
+ let settled = false;
83
+ const settleError = (error) => {
84
+ if (settled)
85
+ return;
86
+ settled = true;
87
+ rejectCallback(error);
88
+ };
89
+ const settleSuccess = (data) => {
90
+ if (settled)
91
+ return;
92
+ settled = true;
93
+ resolveCallback(data);
94
+ };
95
+ const baseUrl = getBaseUrl().replace(/\/$/u, '');
96
+ const server = createServer(async (request, response) => {
97
+ const callbackUrl = new URL(request.url ?? '/', 'http://127.0.0.1');
98
+ if (request.method !== 'GET' || callbackUrl.pathname !== '/callback') {
99
+ response.writeHead(404).end();
100
+ return;
101
+ }
102
+ if (callbackUrl.searchParams.get('state') !== state) {
103
+ response.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
104
+ response.end(callbackHtml('Login failed', 'State verification failed. Return to the terminal and try again.'));
105
+ settleError(new Error('Login state verification failed'));
106
+ return;
107
+ }
108
+ const code = callbackUrl.searchParams.get('code');
109
+ if (!code) {
110
+ response.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });
111
+ response.end(callbackHtml('Login failed', 'The callback did not include an exchange code.'));
112
+ settleError(new Error('Login callback did not include an exchange code'));
113
+ return;
114
+ }
115
+ try {
116
+ const exchangeResponse = await dependencies.fetch(`${baseUrl}/auth/exchange`, {
117
+ method: 'POST',
118
+ headers: { 'Content-Type': 'application/json' },
119
+ body: JSON.stringify({ code }),
120
+ });
121
+ const envelope = await parseEnvelope(exchangeResponse);
122
+ if (!exchangeResponse.ok || !envelope?.ok) {
123
+ if (exchangeResponse.status === 401)
124
+ throw new Error('Login expired, run `invd login` again');
125
+ throw new Error(envelope && !envelope.ok ? envelope.error : `Login exchange failed (${exchangeResponse.status})`);
126
+ }
127
+ await setApiKey(envelope.data.key);
128
+ response.writeHead(200, {
129
+ 'Cache-Control': 'no-store',
130
+ 'Content-Type': 'text/html; charset=utf-8',
131
+ });
132
+ response.end(callbackHtml('Login complete', 'You can close this tab and return to the terminal.'));
133
+ settleSuccess(envelope.data);
134
+ }
135
+ catch (error) {
136
+ const exchangeError = error instanceof Error ? error : new Error(String(error));
137
+ response.writeHead(502, {
138
+ 'Cache-Control': 'no-store',
139
+ 'Content-Type': 'text/html; charset=utf-8',
140
+ });
141
+ response.end(callbackHtml('Login failed', 'The credential exchange failed. Return to the terminal and try again.'));
142
+ settleError(exchangeError);
143
+ }
144
+ });
145
+ const port = await listenOnRandomPort(server);
146
+ const loginUrl = new URL(`${baseUrl}/auth/login`);
147
+ loginUrl.searchParams.set('port', String(port));
148
+ loginUrl.searchParams.set('state', state);
149
+ loginUrl.searchParams.set('hostname', hostname().slice(0, 64));
150
+ if (options.team)
151
+ loginUrl.searchParams.set('team', options.team);
152
+ const handleInterrupt = () => settleError(new Error('Login cancelled'));
153
+ process.once('SIGINT', handleInterrupt);
154
+ const timeout = setTimeout(() => settleError(new Error('Login timed out. Run `invd login` again.')), dependencies.timeoutMs);
155
+ try {
156
+ const preflight = await dependencies.fetch(loginUrl, { redirect: 'manual' });
157
+ if (preflight.status === 503) {
158
+ throw new Error('OAuth login is not enabled on this deployment. Use `invd config set-key` instead.');
159
+ }
160
+ if (preflight.status < 300 || preflight.status >= 400) {
161
+ const envelope = await parseEnvelope(preflight);
162
+ throw new Error(envelope && !envelope.ok ? envelope.error : `Could not start login (${preflight.status})`);
163
+ }
164
+ try {
165
+ await dependencies.openBrowser(loginUrl.toString());
166
+ console.log(chalk.dim('Opening your browser to complete login...'));
167
+ }
168
+ catch {
169
+ console.warn(chalk.yellow('Could not open a browser automatically. Open this URL:'));
170
+ console.log(loginUrl.toString());
171
+ }
172
+ const data = await callback;
173
+ const approximateExpiry = new Date(Date.now() + KEY_LIFETIME_MS).toLocaleDateString();
174
+ console.log(chalk.green('Logged in successfully.'));
175
+ console.log(` Team: ${data.teamId}`);
176
+ console.log(` Key hint: ${data.keyHint}`);
177
+ console.log(` Label: ${data.label}`);
178
+ console.log(` Expires: approximately ${approximateExpiry} (90 days)`);
179
+ console.log(chalk.dim('This sign-in is also visible in the web UI under Data API keys.'));
180
+ return data;
181
+ }
182
+ finally {
183
+ clearTimeout(timeout);
184
+ process.off('SIGINT', handleInterrupt);
185
+ await closeServer(server);
186
+ }
187
+ }
188
+ export async function logout(dependencies = defaultDependencies) {
189
+ let resolved;
190
+ try {
191
+ resolved = await resolveApiKey();
192
+ }
193
+ catch (error) {
194
+ if (error instanceof Error && error.message.startsWith('No API key configured.')) {
195
+ console.log('Not logged in.');
196
+ return;
197
+ }
198
+ throw error;
199
+ }
200
+ const baseUrl = getBaseUrl().replace(/\/$/u, '');
201
+ try {
202
+ const response = await dependencies.fetch(`${baseUrl}/auth/revoke`, {
203
+ method: 'POST',
204
+ headers: { Authorization: `Bearer ${resolved.key}` },
205
+ });
206
+ if (!response.ok) {
207
+ const envelope = await parseEnvelope(response);
208
+ console.warn(chalk.yellow(`Warning: remote revocation failed: ${envelope && !envelope.ok ? envelope.error : response.status}`));
209
+ }
210
+ }
211
+ catch (error) {
212
+ console.warn(chalk.yellow(`Warning: remote revocation failed: ${errorMessage(error)}`));
213
+ }
214
+ if (resolved.source === 'environment') {
215
+ console.log('The active key comes from INVINITE_DATA_API_KEY. Remove that environment variable to finish logging out.');
216
+ return;
217
+ }
218
+ if (resolved.source === 'dotenv') {
219
+ console.log('The active key comes from the current directory\'s .env file. Remove INVINITE_DATA_API_KEY from that file to finish logging out.');
220
+ return;
221
+ }
222
+ await clearApiKey();
223
+ console.log(chalk.green('Logged out locally.'));
224
+ }
225
+ export function registerLoginCommands(program) {
226
+ program
227
+ .command('login')
228
+ .description('Log in through your browser')
229
+ .option('--team <teamId>', 'Choose a team for the new API key')
230
+ .action(async (options) => {
231
+ try {
232
+ await login(options);
233
+ }
234
+ catch (error) {
235
+ console.error(chalk.red(errorMessage(error)));
236
+ process.exitCode = 1;
237
+ }
238
+ });
239
+ program
240
+ .command('logout')
241
+ .description('Revoke the current login and clear local credentials')
242
+ .action(async () => {
243
+ try {
244
+ await logout();
245
+ }
246
+ catch (error) {
247
+ console.error(chalk.red(errorMessage(error)));
248
+ process.exitCode = 1;
249
+ }
250
+ });
251
+ }
252
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,9 @@
1
+ export type ApiKeySource = 'environment' | 'dotenv' | 'keychain' | 'config';
2
+ export interface ResolvedApiKey {
3
+ key: string;
4
+ source: ApiKeySource;
5
+ }
6
+ export declare function resolveApiKey(): Promise<ResolvedApiKey>;
1
7
  export declare function getApiKey(): Promise<string>;
2
8
  export declare function setApiKey(key: string): Promise<void>;
9
+ export declare function clearApiKey(): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- import { getStoredApiKey, setStoredApiKey } from './config-manager.js';
3
+ import { deleteStoredApiKey, getStoredApiKey, setStoredApiKey } from './config-manager.js';
4
4
  async function tryKeytar() {
5
5
  try {
6
6
  // Dynamic import - keytar is optional
@@ -36,27 +36,31 @@ function readDotEnvKey() {
36
36
  }
37
37
  const SERVICE = 'invinite-data-cli';
38
38
  const ACCOUNT = 'api-key';
39
- export async function getApiKey() {
39
+ export async function resolveApiKey() {
40
40
  // 1. Environment variable (highest priority)
41
41
  const envKey = process.env.INVINITE_DATA_API_KEY;
42
42
  if (envKey)
43
- return envKey;
43
+ return { key: envKey, source: 'environment' };
44
44
  // 2. .env file in current working directory
45
45
  const dotEnvKey = readDotEnvKey();
46
46
  if (dotEnvKey)
47
- return dotEnvKey;
47
+ return { key: dotEnvKey, source: 'dotenv' };
48
48
  // 3. OS keychain via keytar
49
49
  const keytar = await tryKeytar();
50
50
  if (keytar) {
51
51
  const keychainKey = await keytar.getPassword(SERVICE, ACCOUNT);
52
52
  if (keychainKey)
53
- return keychainKey;
53
+ return { key: keychainKey, source: 'keychain' };
54
54
  }
55
55
  // 4. Conf fallback
56
56
  const storedKey = getStoredApiKey();
57
57
  if (storedKey)
58
- return storedKey;
59
- throw new Error('No API key configured. Set INVINITE_DATA_API_KEY in your environment or .env file, or run: invd config set-key');
58
+ return { key: storedKey, source: 'config' };
59
+ throw new Error('No API key configured. Run: invd login');
60
+ }
61
+ export async function getApiKey() {
62
+ const resolved = await resolveApiKey();
63
+ return resolved.key;
60
64
  }
61
65
  export async function setApiKey(key) {
62
66
  const keytar = await tryKeytar();
@@ -67,4 +71,15 @@ export async function setApiKey(key) {
67
71
  setStoredApiKey(key);
68
72
  }
69
73
  }
74
+ export async function clearApiKey() {
75
+ const keytar = await tryKeytar();
76
+ try {
77
+ if (keytar) {
78
+ await keytar.deletePassword(SERVICE, ACCOUNT);
79
+ }
80
+ }
81
+ finally {
82
+ deleteStoredApiKey();
83
+ }
84
+ }
70
85
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/config/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/config/auth.ts"],"names":[],"mappings":"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"}
@@ -2,5 +2,6 @@ export declare function getBaseUrl(): string;
2
2
  export declare function setBaseUrl(url: string): void;
3
3
  export declare function getStoredApiKey(): string | undefined;
4
4
  export declare function setStoredApiKey(key: string): void;
5
+ export declare function deleteStoredApiKey(): void;
5
6
  export declare function resetConfig(): void;
6
7
  export declare function showConfig(): Record<string, unknown>;
@@ -25,6 +25,9 @@ export function getStoredApiKey() {
25
25
  export function setStoredApiKey(key) {
26
26
  config.set('apiKey', key);
27
27
  }
28
+ export function deleteStoredApiKey() {
29
+ config.delete('apiKey');
30
+ }
28
31
  export function resetConfig() {
29
32
  config.clear();
30
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../../src/config/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAe;IACpC,WAAW,EAAE,mBAAmB;IAChC,MAAM,EAAE;QACN,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,2BAA2B;SACrC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;SACZ;KACF;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,UAAU;IACxB,OAAO,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,GAAG,IAAI,SAAS,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,OAAO,EAAE,UAAU,EAAE;QACrB,SAAS,EAAE,CAAC,CAAC,eAAe,EAAE;KAC/B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../../src/config/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAe;IACpC,WAAW,EAAE,mBAAmB;IAChC,MAAM,EAAE;QACN,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,2BAA2B;SACrC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;SACZ;KACF;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,UAAU;IACxB,OAAO,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,GAAG,IAAI,SAAS,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,OAAO,EAAE,UAAU,EAAE;QACrB,SAAS,EAAE,CAAC,CAAC,eAAe,EAAE;KAC/B,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invinite-org/invinite-data-cli",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "type": "module",
5
5
  "description": "CLI for the Invinite Data API",
6
6
  "publishConfig": {