> ## Documentation Index
> Fetch the complete documentation index at: https://rapidreview.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI reference

> Every nisa command, flag, and exit code. Direct commands are free and fast; four chat-backed commands create a model turn and are usage-tracked.

`nisa` with no subcommand opens the terminal chat (TUI). Everything below is headless-friendly: stdout is the payload (JSON, BibTeX, CSV, plain text, or bytes); stderr carries the session id, tool activity, the usage footer, and errors.

## Global flags

| Flag                  | Notes                                                                                                                                                                                                                                                            |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--headless`          | No interactive prompts, ever. Auto-inferred when stderr isn't a TTY. Missing auth → message on stderr, exit 1.                                                                                                                                                   |
| `--envelope`          | Wrap the JSON of `search`, `semantic-search`, `paper`, `related`, `excerpts`, `lists`, `list-papers` as `{meta:{command,duration_ms,…}, data:…}`. Ignored for `--format bibtex\|csv`; `cite`, `pdf`, and the session, key, and usage commands are never wrapped. |
| `--api-url <URL>`     | Target another backend. **Must come before the subcommand**: `nisa --api-url http://127.0.0.1:5001 sessions`.                                                                                                                                                    |
| `--help`, `--version` |                                                                                                                                                                                                                                                                  |

## Exit codes

| Code  | Meaning                                                                     |
| ----- | --------------------------------------------------------------------------- |
| `0`   | success                                                                     |
| `1`   | error — including a rate-limit trip and missing auth in headless mode       |
| `124` | `--timeout` hit (matches GNU `timeout`); a partial answer is still returned |
| `130` | interrupted (Ctrl-C); the session is interrupted cleanly first              |
| `141` | broken pipe (e.g. `\| head`); exits silently                                |

## Direct commands

<Badge color="green">free</Badge> Index and database lookups. About a second. No model turn.

### `nisa search [QUERY]`

BM25 over the corpus, blended with citation counts.

| Flag                       | Default | Notes                                                                                                                                                        |
| -------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `QUERY`                    | —       | Or `--query <Q>` (repeatable, **max 8** — parallel fan-out, deduped by `arxiv_id`, re-sorted) or `--stdin` (one query per line; blank and `#` lines skipped) |
| `--max-results <N>`        | `10`    | Server cap 50                                                                                                                                                |
| `--offset <N>`             | `0`     | Paginates the merged list; silently clamped at 500 (`semantic-search`: 200)                                                                                  |
| `--author <STR>`           | —       |                                                                                                                                                              |
| `--date-from`, `--date-to` | —       | `YYYY-MM-DD`, `YYYY-MM`, `YYYYMM`, or `YYYY`; month precision. Bare year in `--date-to` = December. Unparseable values are rejected, not dropped             |
| `--format`                 | `json`  | `json` \| `bibtex` \| `csv`                                                                                                                                  |

Response: `{query|queries, papers:[{arxiv_id,title,year,authors,citation_count,score,snippets,url}], count, offset, limit, truncated, pagination_hint, index_latest_pub_month}`.

<Warning>
  Ranking blends BM25 with citations, so a recent low-citation paper ranks far below an older well-cited one. An absent recent paper is a ranking artifact, not evidence it doesn't exist — check `index_latest_pub_month` before concluding anything from an empty recency window.
</Warning>

### `nisa semantic-search [QUERY]`

Embedding search over abstracts. Same shape as `search`, except: `--query` cap is **4** (each query is one embedding call); `--year-min` / `--year-max` replace the date flags; papers carry `similarity` and `abstract` instead of `score` and `snippets`.

### `nisa paper <ARXIV_ID>`

Title, authors, abstract, year, citation count, categories, graph cluster, PageRank, URL. No flags.

### `nisa related <ARXIV_ID>`

Hybrid citation-graph proximity + semantic similarity. The best "find related work" tool.

| Flag              | Default                                                                                                                                                            |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--n <N>`         | `10` (1–50)                                                                                                                                                        |
| `--min-score <F>` | none — run without it first. `similarity_score` is an open-ended absolute value (thousands for a famous paper), not a percentage; recent or niche papers score low |
| `--format`        | `json` \| `bibtex` \| `csv`                                                                                                                                        |

### `nisa excerpts <ARXIV_ID> --query <Q>`

Passages from the paper's full text matching the query (tokenized OR; quoted phrases match exactly). `--max <N>` default `10` (1–50). Returns `excerpts:[{index, text}]` (plus `excerpts_raw`, `count`, `truncated`) with `matched_terms`, `missing_terms`, `doc_found`, `full_text_indexed` — check those before treating zero excerpts as absence. `--format bibtex|csv` is rejected.

### `nisa search-status <SESSION_ID>`

Polls an agent-enriched search started through the HTTP API (`enrich: true`) for newly surfaced papers; `--last-count`, `--last-action-count` return only what's new. `nisa search` itself is direct and never starts one.

### `nisa cite <ARXIV_ID>`

One BibTeX `@misc` entry with `archivePrefix = {arXiv}`. Formatted client-side.

### `nisa pdf <ARXIV_ID>`

Prints `{pdf_url}`; `--out <PATH>` downloads the bytes. Uses the cached copy when available, else arxiv.org.

### Paper lists

| Command                                      | Flags                        |
| -------------------------------------------- | ---------------------------- |
| `nisa lists`                                 | —                            |
| `nisa list-papers <LIST_ID>`                 | `--format json\|bibtex\|csv` |
| `nisa create-list <NAME>`                    | `--emoji <STR>`              |
| `nisa delete-list <LIST_ID>`                 | —                            |
| `nisa add-to-list <LIST_ID> <ARXIV_ID>`      | `--note <STR>`               |
| `nisa remove-from-list <LIST_ID> <ARXIV_ID>` | —                            |

Lists sync with the web app both ways.

## Chat-backed commands

<Badge color="orange">usage-tracked</Badge> Each creates an agent turn on the backend: 30–120 s typical. Rate-limited per machine to **10 per minute, 100 per hour** (exit 1 with a wait hint when tripped). The backend can't yet serve many concurrent research turns — use `ask-batch` rather than a hand-rolled parallel loop. Direct commands are not limited.

All chat-backed commands emit JSON with `ok`, `session_id`, `answer`, `arxiv_ids`, `tokens.cost_usd`, `duration_ms` — on success and failure alike.

<Note>
  All commands are free today. `cost_usd` fields populate for observability; `--estimate` and `--max-cost` exist for when billing comes online.
</Note>

### `nisa ask [MESSAGE]`

One question, one answer, ephemeral session (deleted on `ok: true` unless `--keep`).

| Flag                                       | Notes                                                                       |
| ------------------------------------------ | --------------------------------------------------------------------------- |
| `MESSAGE`                                  | `-` reads stdin (or `--stdin`)                                              |
| `--timeout <S>`                            | Exit 124 on expiry; partial answer returned; session kept                   |
| `--schema <JSON>` / `--schema-file <PATH>` | Ask for structured output; parsed reply in `answer_json` alongside `answer` |
| `--keep`                                   | Don't auto-delete the session                                               |
| `--estimate`                               | Don't run; print `{estimated_cost_usd,…}` (heuristic). Not rate-limited     |

### `nisa exec [MESSAGE]`

Multi-turn, streaming. Stdout is the reply (NDJSON with `--json`).

| Flag                                              | Notes                                                                                      |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `--session-id <ID>` / `--continue`, `-c`          | Resume a session / the most recent one                                                     |
| `--detach`                                        | Send, print the session id, exit. Pair with `nisa wait`. Not combinable with `--workspace` |
| `--json`, `--show-tools`, `--quiet`, `--no-usage` | Output control                                                                             |
| `--timeout <S>`                                   | Exit 124                                                                                   |
| `--workspace <DIR>`                               | Expose local read tools (`fs.read_file`, `fs.list_dir`, `fs.glob`, `fs.grep`)              |
| `--allow-writes`                                  | + `fs.write_file`, `fs.edit_file` (no effect without `--workspace`)                        |
| `--allow-exec`                                    | + `shell.exec`, 60 s default command timeout (no effect without `--workspace`)             |
| `--approvals prompt\|auto\|deny`                  | Default `auto` for `exec`                                                                  |

`nisa chat` is the legacy verbose form of `exec` (full event stream, `--approvals` defaults to `prompt`); prefer `exec`.

### `nisa ask-batch`

One question per input line, one JSON object per output line. Sequential by design; one invocation uses one rate-limit slot.

| Flag                    | Notes                                                                      |
| ----------------------- | -------------------------------------------------------------------------- |
| `--input <PATH>`        | Default stdin                                                              |
| `--timeout <S>`         | Per question                                                               |
| `--schema <JSON>`       | Shared across questions                                                    |
| `--max-cost <USD>`      | Cumulative ceiling; remaining questions emit `{ok:false, skipped:true, …}` |
| `--keep`, `--fail-fast` | Default continues past failures                                            |

### `nisa wait <SESSION_ID>`

Block until an in-flight turn completes (pairs with `exec --detach`). Counts against the chat rate limit. Flags: `--json`, `--show-tools`, `--quiet`, `--no-usage`, `--timeout <S>`.

## Sessions

<Badge color="green">free</Badge> except `send`, which starts a model turn like `exec` (usage-tracked, and not counted by the CLI's rate limiter).

| Command                                    | Flags                                         |
| ------------------------------------------ | --------------------------------------------- |
| `nisa sessions`                            | `--limit <N>`, `--query <STR>` (title filter) |
| `nisa new`                                 | —                                             |
| `nisa state <SESSION_ID>`                  | —                                             |
| `nisa send <SESSION_ID> <MESSAGE>`         | —                                             |
| `nisa stream <SESSION_ID>`                 | `--after-seq <N>`                             |
| `nisa interrupt <SESSION_ID>`              | —                                             |
| `nisa delete <SESSION_ID>`                 | —                                             |
| `nisa artifacts <SESSION_ID>`              | —                                             |
| `nisa artifact <SESSION_ID> <ARTIFACT_ID>` | `--out <PATH>`                                |
| `nisa export <SESSION_ID>`                 | `--format markdown\|json`, `--out <PATH>`     |

`ask` sessions auto-delete on success; `exec` sessions persist until `nisa delete` or backend retention.

## Setup, keys, diagnostics

<Badge color="green">free</Badge>

| Command                                                                                                                                              | Notes                                                                                                               |
| ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `nisa login [--no-browser]`                                                                                                                          | Browser sign-in (OAuth only; mints no key)                                                                          |
| `nisa logout`                                                                                                                                        | Deletes the local credentials file only                                                                             |
| `nisa whoami [--json]`                                                                                                                               |                                                                                                                     |
| `nisa keys list`                                                                                                                                     | `{keys:[{id,name,key_prefix,created_at,last_used_at}]}` — raw keys are never stored server-side                     |
| `nisa keys create <NAME>`                                                                                                                            | Raw `rr_sk_…` key printed **once**                                                                                  |
| `nisa keys revoke <KEY_ID>`                                                                                                                          |                                                                                                                     |
| `nisa usage [--days N] [--group-by day\|model\|agent_type]`                                                                                          | Default 30 days; `{breakdown, totals:{prompt_tokens,completion_tokens,cached_tokens,request_count,total_cost_usd}}` |
| `nisa doctor [--json]`                                                                                                                               | Install, PATH, platform, backend, config, auth. Never prints secrets                                                |
| `nisa upgrade [--check]`                                                                                                                             | Re-runs the installer; `--check` exits 1 if an upgrade exists                                                       |
| `nisa tui [--session-id <ID>]`                                                                                                                       | Same as bare `nisa`                                                                                                 |
| `nisa bridge --workspace <DIR> (--claim <TOKEN> \| --session-id <ID>) [--allow-writes] [--allow-exec] [--idle-timeout <S>] [--approvals auto\|deny]` | Attach this machine's folder to a web chat session; `--claim` takes the one-time `brg_…` token the web app shows    |

<Note>
  `keys` requires your browser sign-in to be the credential in use (`nisa doctor --json` → `auth.source: oauth_credentials`). With `RAPIDREVIEW_KEY` set — or the key the CLI's browser onboarding stores — all three answer `403 API key management requires browser login`. Create keys in the web app (**Settings → API Keys**), or `nisa logout && nisa login` first.
</Note>

## Terminal chat

Slash commands, permissions, and `!` commands are on [Terminal chat](/docs/nisa/guides/terminal-chat).
