Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📡 air

the official air CLI — look up any site's AI Rank from your terminal

npm node zero deps license airanks.net

npm install -g air-cliair example.com → done. ✅


🤖 What is AIR?

AIR (Artificial Intelligence Ranking) by airanks makes AI optimization visible — a single 0–10 score for how discoverable a domain is inside AI-generated answers. See any site's AI Rank at airanks.net, or install the toolbar to see it while you browse.

air is the reference command-line client: a zero-dependency, single-file Node.js CLI that hits the exact same public API as the toolbar — the number you get here is the number you'd get there. 🧮


📚 Table of contents


🧭 How it works

A domain that's never been looked up before gets hydrated on the spot — the CLI just polls until the result is ready.

flowchart TD
    A["$ air example.com"] --> B{Looks like a domain?}
    B -- "yes (or -d)" --> C["GET /api/v1/domains/{host}"]
    B -- "no, or -k/-p" --> S["GET /api/v1/search?q=..."]
    S --> R1["render domains / brands / phrases"]

    C --> D{HTTP 429?}
    D -- yes --> E["sleep Retry-After<br/>(clamped to remaining deadline)"] --> C
    D -- no --> F{ai_files.status<br/>== pending?}
    F -- "yes, budget left" --> G["🌀 spinner + countdown<br/>(AIR_POLL_MS)"] --> C
    F -- "yes, deadline hit" --> P["render 'still gathering'<br/>exit code 2"]
    F -- no --> H["render AIR score,<br/>gauge, ai_files, summary<br/>exit code 0"]
Loading

One wall-clock deadline (AIR_POLL_MAX_MS) covers the whole lookup — both 429 back-off sleeps and pending-poll waits count against it. A cold first hit is usually well under a minute; cached domains return instantly.


📦 Install

npm install -g air-cli
  • Requires Node.js 18+
  • Zero runtime dependencies — one file, air.js, ships as the whole package
  • Installs a global air binary (see bin in package.json)

🚀 Quickstart

# Look up a domain's AIR score
air example.com

# Search by brand or phrase instead of a domain
air "best crm software"

# Force domain vs. keyword search explicitly
air -d example.com
air -k "project management tools"

# Machine-readable output for scripts / CI
air example.com --json

# Plain text — no color, no icons (also auto-detected for CI / TERM=dumb)
air example.com --txt
🖥️ Sample terminal output (colors, gauge, and Nerd Font glyphs not shown in Markdown)
  🌐 example.com   🏆 AIR 7.4/10  ██████████░░░  · top 12%

  📊 tracked — 213 occurrences · 41 phrases · 9 brands
  📄 llms.txt ✅  llms-full ❌  ai.txt ❌  robots.txt ✅  json-ld ✅ (Organization)
  🛡️ ai crawlers: 6 allowed · 2 partial ✔ of 8

  A one-line lede pulled straight from the API's summary field, italicized,
  wrapped to the terminal width, the rest set in plain text.

  ──────────────────────────────────────────────────────────────────
  🔗 airanks.net/page?d=example.com  ·  🗄️ dataset 2026-08-14

Icons are Font Awesome codepoints — they render with any Nerd Font / FA-patched terminal font. --txt (or NO_COLOR, TERM=dumb, CI=true) drops ANSI color; --txt additionally drops the icons and gauge and falls back to plain words like yes/no.


🗂️ Commands

Command What it does
air <domain|keyword> Look up a domain's AIR score, or search domains/brands/phrases if the input isn't a domain
air login Interactive: paste an API key, or log in via your browser (device-code style, PKCE)
air logout Remove the locally saved token (server-side token stays valid until it expires)
air whoami Show who you're logged in as, and which tier the token grants
air --help / -h Show usage

A bare, never-before-seen argument is auto-classified: something that parses as a hostname (example.com) is looked up as a domain; anything else ("best crm software") is searched across domains, brands, and phrases. Override the guess with -d/-k below.

🔑 First run & browser login (click to expand)

The very first time you run air interactively with no saved key, it offers a one-time setup wizard: paste an API key, log in via browser, or continue anonymously (recorded so you're never asked again). air login re-runs the same chooser any time.

sequenceDiagram
    autonumber
    participant CLI as air login
    participant API as airanks.net API
    participant Browser as Your browser

    CLI->>API: POST /cli/auth {code_challenge}  (PKCE, RFC 7636 S256)
    API-->>CLI: {browser_url, confirmation_code, nonce, interval}
    CLI->>Browser: open browser_url (same-origin only)
    Note over CLI: prints confirmation_code either way
    loop until confirmed or expired
        CLI->>API: POST /cli/auth/poll {nonce, code_verifier}
        API-->>CLI: pending | ok(token) | denied | expired
    end
    CLI->>CLI: save token to ~/.config/air/auth.json (mode 0600)
Loading

Over SSH or on a headless Linux box (no DISPLAY), the CLI skips auto-opening a browser and just prints the URL + code to enter on any device.


🚩 Options

Flag Description
-d, --domain Force domain lookup
-k, --keyword, -p, --phrase Force keyword/phrase search
--json Emit raw JSON instead of formatted output
--txt Plain text, no ANSI color or icons
-h, --help Show usage

🔐 Shared authentication

One login works across every AIR client — this CLI, the MCP server, the SDKs, and friends. Resolution order, first match wins:

flowchart LR
    A["AIR_API_KEY env var set?"] -- yes --> T1["✅ use it — always attaches,\neven cross-host"]
    A -- no --> B["~/.config/air/auth.json exists?"]
    B -- no --> AN["👤 anonymous tier\n(rate-limited)"]
    B -- yes --> C{"saved token's host ==\ncurrent API host?"}
    C -- yes --> T2["✅ use saved token"]
    C -- no --> AN
Loading
  • AIR_API_KEY (env) — highest priority, ideal for CI/scripts, always attached regardless of AIR_API_BASE.
  • ~/.config/air/auth.json — written by air login; only attaches to the host it was minted for, so a token never leaks to a different AIR_API_BASE.
  • anonymous — no key found anywhere; still fully functional, just rate-limited. air login lifts the limit.

🌱 Environment variables

Variable Purpose
AIR_API_KEY API key, takes priority over a saved login
AIR_API_BASE Override the API base URL (default https://airanks.net/api/v1)
AIR_POLL_MS Polling interval while a first-time lookup is gathering
AIR_POLL_MAX_MS Total deadline for a lookup before giving up
AIR_NO_UPDATE Disable the once-a-day auto-upgrade check entirely
NO_COLOR Disable ANSI color only (icons stay)

🎨 Output modes

Mode Trigger Color Icons Gauge
Rich TTY default, interactive terminal ✅ truecolor ✅ Nerd Font glyphs
NO_COLOR NO_COLOR env set
--txt --txt flag, TERM=dumb, or CI=true ❌ (→ yes/no words)
--json --json flag — raw API JSON on stdout —

Score coloring runs a red → amber → green truecolor ramp (0 → 10); clickable airanks.net/page links use OSC 8 hyperlinks in terminals that support them (iTerm2, kitty, Ghostty, WezTerm) and degrade to plain text everywhere else.


🚦 Exit codes

Code Meaning
0 Success
1 Hard failure — bad input, auth error, or a rate limit that outlasted the deadline
2 Domain is still being gathered — re-run in a bit (never printed as a fake 0/10)

🔄 Auto-upgrade

Once every 24 hours, on an interactive run only (never in pipes, --json, --txt, or CI), air checks the npm registry for a newer air-cli and self-installs it via npm install -g air-cli@latest. Fully non-fatal — offline, a slow registry, or a permission error just gets silently skipped and your lookup still runs. Opt out entirely with AIR_NO_UPDATE=1.


🧪 Development

git clone https://git.shoemoney.ai/airanks-net/node-cli.git
cd node-cli
npm test          # node --test — unit + CLI smoke tests, no network

No build step — air.js is the shipped artifact, run directly.


🌐 The airanks ecosystem

node-cli is one client among several, all speaking the same public API and sharing the same login:

Repo What it is
chrome-extension The AIR toolbar — AI optimization in your browser
rust-cli · go-cli air in Rust and Go
js-sdk · python-sdk Programmatic SDKs for Node/browser and Python
composer-package PHP API client
mcp-server MCP server — air_rank / air_files / air_search tools for any agent
agent-toolkit Giving AI agents (Claude, Codex, Cursor, Hermes) access to AIR
acp-agent · acp-zed ACP agents (BeeAI protocol, and Zed's editor-native protocol)
homebrew-tap brew install for the air CLI
claude-skills Claude skills for AIR, including narrated video generation

📄 License

MIT — see LICENSE. 🎉

Built for the terminal-first. If your AIR score made you laugh or cry, that's the score doing its job. 😅

About

air — the airanks CLI for AI optimization: look up any site's AI Rank from your terminal. airanks.net

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages