alden

Commands

Run alden <command> --help for the same information in your terminal.

In a terminal, alden queue, alden review and alden doctor end with a dim "Next:" line suggesting the obvious next command: alden review 1 for the top of the queue, alden open <#> or alden ui after a review, the fix doctor found. It never appears with --json or when the output goes to a pipe or a file.

alden (interactive)

alden

On its own in a terminal, alden opens a full-screen view of your queue: brief a PR, mark its places useful or not, write comments and send your review without leaving it. It draws with the same renderers as alden queue, alden review and alden send, so what you see is what they print. Quit with q (or Ctrl-C anywhere), and the terminal is as you left it.

It opens only when both standard input and output are a terminal, outside CI (CI set) and not on a dumb terminal (TERM=dumb). Otherwise alden prints its help, as before; alden --help always does, and every command works as it always has. It needs you signed in (alden auth login), and respects NO_COLOR. 80 by 24 or bigger works best; a smaller terminal cuts long lines, and one too small to use says so. It redraws when you resize it.

The queue screen is alden queue's table: Your turn first (when you have one), then Needs you and Fast-track, ranked. While it loads it says what it's doing, and checks the PRs you reviewed for follow-ups, as alden queue does. Briefing or opening a PR from Your turn marks what happened as seen, as alden review and alden open do, and a briefing opened here starts its time to review as one opened in the terminal. A briefing is alden review's, without the model until you press m: then it says which model and what a review may cost against your caps, and runs only on y, saying what it cost. u and n record feedback as alden ui does (the same mark again takes it back), and say how close a lesson is. c writes a draft comment as alden comment does: on the place's file and line, or a general note when the cursor isn't on a place. s shows exactly what alden send would post; nothing is sent until you press Enter and then y. Afterwards it's back to the queue, asked for again.

Screen Key What it does
Queue j / k, ↓ / ↑ Move down or up a PR. g / G the first or last; space and b half a screen.
Queue / Search as you type: title, repo, #number, author (@sam), branch. Enter keeps it, Esc puts it back; Esc on the queue clears it.
Queue Enter Brief the selected PR (checks and the code graph, no model).
Queue o Open the selected PR on GitHub.
Queue r Ask GitHub again, skipping the 60-second cache.
Queue q Quit.
Briefing j / k, ↓ / ↑ Move the cursor a line; the place it's on is marked. Space / b a screen down or up, g / G the top or bottom.
Briefing 1–9 Go to that place under "Needs your eyes".
Briefing u / n Mark the place under the cursor useful / not useful. Again takes it back.
Briefing c Write a comment on the place under the cursor (a general note elsewhere). Enter saves it as a draft, Esc cancels, Ctrl-U clears.
Briefing s The send screen.
Briefing m Run the model on this PR, after saying which and what it may cost; y runs it.
Briefing o Open the PR on GitHub.
Briefing Esc, q Back to the queue.
Send Tab / Shift-Tab, c a x Comment, Approve or Request changes. Approve also lists the places you didn't comment on.
Send j / k, space / b, g / G Scroll.
Send Enter, then y Send the review to GitHub. Any other key after Enter doesn't send.
Send Esc, q Back to the briefing.
Anywhere Ctrl-C Quit.

alden --version

Prints Alden's version. When a newer Alden is out, it also says so, with how to upgrade, on standard error so scripts reading the version aren't affected. It asks npm at most once a day; alden config set updates.check false or ALDEN_NO_UPDATE_CHECK turns this off. alden doctor reports the same.

alden setup

Sets up a model in about a minute. In a terminal it asks which of three you want:

  1. Paste an API key, Anthropic's or OpenAI's: Alden tells them apart (sk-ant-… is Anthropic's, any other sk-… OpenAI's; Claude.ai sign-in tokens and admin keys are refused). It links to where you create each, reads the key without showing it, checks it with one tiny request to its provider (Claude Haiku for one output token, or gpt-6-luna for a few: a fraction of a cent), and stores it as alden auth model does. A key the provider refuses isn't stored, and it says why: mistyped or deleted, no credit, or no permission. When the provider can't be reached, it offers to store the key unchecked. Its provider then becomes the model (an OpenAI key picks gpt-6.1-sol unless you'd chosen an OpenAI model).
  2. Use a local model. Looks for Ollama (at OLLAMA_HOST, or http://localhost:11434), lists what it has pulled, and recommends a model for your machine's memory (see Models). Choosing one it hasn't pulled downloads it with progress; then it sets model.provider, model.name and, when Ollama isn't at its default address, model.baseUrl.
  3. Checks only. Changes nothing.

Outside a terminal (a pipe, a script), it prints what it would offer and the commands to do each by hand, and exits with 0. In a terminal, it exits with 1 when no model was set up (except for checks only). alden doctor suggests it when there's no model.

alden auth

Sign in to GitHub, and store your Anthropic or OpenAI API key.

Command What it does
alden auth login Uses the GitHub CLI's sign-in if there is one. Otherwise signs you in with a code in your browser and stores the token.
alden auth login --device Signs in with a one-time code, even if the GitHub CLI is signed in. Press Enter to open the GitHub page for it.
alden auth login --with-token Reads a token from standard input, e.g. echo $TOKEN | alden auth login --with-token.
alden auth status Shows the account Alden is using, where the token comes from, and its scopes; and where the model's key comes from (never the key). Signed out, it says whether the keychain refused to answer.
alden auth logout Removes the token Alden stored. Doesn't touch the GitHub CLI's sign-in.
alden auth model Asks for your Anthropic or OpenAI API key without showing it (or reads it from standard input, e.g. pbpaste | alden auth model), tells which it is from its shape, and stores it in the OS keychain under its provider's name. The desktop app, alden ui and alden mcp use it too. If the provider you use has no key, the pasted key's provider becomes the model; otherwise it says how to switch. alden setup does the same after checking the key works.
alden auth model --remove Removes the keys Alden stored, both unless --provider anthropic or --provider openai says which.

Alden looks for a token in this order:

  1. The ALDEN_GITHUB_TOKEN environment variable.
  2. The token Alden stored, in the OS keychain (or, where there's no keychain, a file only you can read).
  3. The GitHub CLI's token (gh auth token).

For the model key's order, see Models.

alden queue

Ranks the open PRs waiting on your review, within what your queue covers on this machine (queue.orgs, queue.repos and queue.ignore; see Configuration). See The review queue.

While it works, a spinner on standard error says what it's doing ("Checking acme/shop (2 of 5)…"). It shows only in a terminal, and never on standard output, so scripts reading the queue get only the queue.

Above Needs you, Your turn lists the PRs you reviewed where something happened you haven't seen, with what and when ("Ana replied to 2 of your comments · 1 resolved", "3h ago"). Its rows aren't numbered: open one by name with alden open acme/shop#12 or alden review acme/shop#12, and it leaves the list. Finding it costs at most one read-only request a minute, shared with the web UI and the desktop app, plus one per PR that changed. See Your turn.

Flag What it does
--repo <owner/name> Only this repo, instead of your queue settings for this run. Repeat for more.
--org <name> Only repos in this organisation, instead of your queue settings for this run. Repeat for more.
--limit <n> The most PRs to fetch. Default 100.
--include-drafts Include draft PRs. Each is tagged [Draft] before its title and dimmed.
--refresh Ignore the 60-second cache.
--author <who> Only PRs by this login, or by people, bots, agents (AI agents) or you.
--label <name> Only PRs with this label (any case).
--search <text> Only PRs whose title, repo, #number, author or branch names contain every word.
--sort <order> rank (the default), age (open longest first), waiting (waited on you longest first), updated (most recent first) or size (smallest first). Sorts inside Needs you and Fast-track separately.
--json Print the ranked queue as JSON. Schema: packages/schema/json/ranked-queue.v1.json. With the flags above, only what they leave (--repo and --org narrow yourTurn too; the others don't).
--explain Under each row, its score by weight and rule, named as [queue.rank] names them: score 6: waiting +3 · risk +2 · ↑ your rule: payments/ first. See Your ranking.

With --author, --label, --search or --sort, a line above the table says what's shown ("12 of 144 PRs: label db"), and alden open and alden review take the numbers as shown.

alden open

alden open <#>
alden open <pr>

Opens a PR in the browser: from your last alden queue by its number in that list, or by name (owner/repo#123 or its URL), as you open one under Your turn. Either way, what happened on it since your review is seen, and it leaves Your turn. alden review <pr> does the same.

alden review

alden review [pr]

Briefs you on a PR, or on your uncommitted local changes when you don't name one. pr can be a PR URL, owner/repo#123, or a number from your last alden queue. See Briefings and checks.

Flag What it does
--no-llm Run only the deterministic checks, without asking a model.
--no-graph Skip the code graph (callers outside the diff).
--model <name> Use this model for this review, e.g. opus, instead of your configured one.
--effort <level> How hard the model thinks: low, medium, high, xhigh or max. Default: the model's own.
--json Print the briefing as JSON. Schema: packages/schema/json/briefing.v1.json.
--markdown Print the briefing as a Markdown document to share or keep: alden review 12 --markdown > briefing.md.

Local reviews cover staged, unstaged and untracked files, compared with HEAD.

--markdown writes the briefing as a document for people: the PR's title, owner/repo#123 with its link, what it does (when the model ran), "Needs your eyes" with each file and line and why, the model's other findings, callers outside the diff, every check with its evidence, what wasn't checked, the files, and a closing line with the model, its cost and when it was briefed. It's the same document as Export → Copy as Markdown in the web UI. Your memory notes and what your feedback changed stay out of it; secrets stay masked as the checks recorded them; terminal control sequences are removed. For example:

# Drop the legacy email column

[acme/shop#412](https://github.com/acme/shop/pull/412) by @sam · main ← sam/drop-email  
3 files · +48/-12

## Needs your eyes
1. **Migration may lose data** (critical) `db/migrate/0042_drop_email.ts:4`
   Dropping a column can't be undone.

## Checked
- ! **Migration may lose data** (critical): A column is dropped.
  - `db/migrate/0042_drop_email.ts:4` drops users.email
- ✓ **Code changed without tests** (inferred from the diff, can be wrong): Tests changed alongside the code.

…

---

Checks only, no model · briefed 2026-10-06 09:30 UTC by Alden

alden comment

alden comment <pr> [file:line[-endLine]] "text" [--suggest "code" | --suggest-file <path> | --suggest -]
alden comment <pr> --threads
alden comment <pr> --reply <thread> "text" [--resolve]
alden comment <pr> --resolve <thread>
alden comment <pr> --draft [--tone terse|concise|detailed|teaching]

Writes a comment on a PR, kept in Alden until you send it with alden send. With file:line, it's on that line of the diff, and with file:12-14 on lines 12 to 14 (one hunk, one side); without, it's a general note for the review's body. A line (or lines) outside the PR's diff, where GitHub won't take an inline comment, becomes a general note that links to it at the PR's head, and Alden says so ("py/orders/tasks.py:5 isn't in the PR's diff, so this goes in the review body with a link to it"); the file and line must exist at the head. See Comments on code outside the diff. With a suggestion, it's a suggested change the author can apply on GitHub, and the text is optional. With no text, lists the PR's comments, ranges and suggestions (old lines and new) shown, outdated ones marked. pr takes the same forms as alden review. See Comments and sending a review.

Flag What it does
--left The line numbers are in the old file: a comment on removed lines. Not with a suggestion.
--suggest <code> Suggests replacement code for the line(s), exactly as they should read. - reads it from stdin; "" deletes the lines. See Suggesting changes.
--suggest-file <path> Suggests the replacement code in this file. From a file or stdin, one trailing newline is dropped.
--delete <id> Deletes a comment (or a reply), by the id the list shows. On one of Alden's drafts, drops it.
--keep <id> Keeps one of Alden's drafts (or all of them on the PR), making it yours so it's sent with your review.
--draft Asks the model, in one call within your caps, to draft comments for the places in the PR's latest briefing (from alden review, of its latest push) that have no comment or draft near them, and says how many it drafted, what it cost and how many places it skipped. They're Alden's drafts: keep them with --keep. Needs a model; never on a PR with text aimed at AI reviewers. See Draft my review.
--tone <tone> With --draft: how Alden writes this time, terse, concise, detailed or teaching, instead of the repo's tone (its own on this machine, else drafts.tone). See The tone of drafts.
--threads Lists the PR's review threads, yours first and open ones first, each with a short id and every comment.
--reply <thread> Replies in a review thread already on the PR (any thread you can reply in, yours or not), by its short id or file:line, with your review. One reply per thread: again changes its text. See Replying in a thread.
--resolve [thread] With --reply, resolves the thread once your review is sent. Alone, names the thread to resolve, saying nothing. Only a thread you started: on someone else's, Alden says so and suggests a reply.
--json Print the comments (or the new one, or with --threads the threads) as JSON. Schema: packages/schema/json/review-draft.v1.json.

alden ask

alden ask <pr> "question" [--model <name>]

Asks your model a question about a PR and prints the answer as it's written, then (on stderr) the model and what the call cost. It answers from the PR's latest briefing of its current push (brief it first with alden review), the diff around the places that matter (lines and files the question names, then the places Alden flagged) and your notes for the repo. One call within your caps, recorded in alden spend as owner/repo#12 question; Ctrl-C stops it. Needs a model; never on a PR with text aimed at AI reviewers. Nothing is kept: each alden ask starts without earlier questions (in alden ui, the last five on a PR are sent along for follow-ups). pr takes the same forms as alden review; --model picks a model for this question only. See Ask about this PR.

alden send

alden send <pr> --comment | --approve | --request-changes [-m body]

Sends the PR's comments to GitHub as one review. First it shows exactly what will post (the body, then each comment with its file and line or lines, each suggestion as the lines it replaces and the lines it suggests, each reply in its thread and whether it resolves it, and before an approval the places Alden flagged that you didn't comment on), then asks. Replies post into the review before it's submitted; threads are resolved after (see How a review with replies is sent). Nothing else in Alden posts to GitHub. Alden's drafts you haven't kept aren't sent, and it says how many; like every draft on the PR, they're cleared once the review is sent. See Comments and sending a review.

Flag What it does
--comment, --approve, --request-changes What the review does. Exactly one.
-m, --message <body> The review's body. General notes follow it.
-y, --yes Send without asking. Without a terminal to ask on, Alden won't send unless you pass it.

alden watch

alden watch [pr] [--off | --rereview | --your-turn | --every-reply | --default]

How much the desktop app tells you about a PR after you review it: its own level, overriding notifications.followUps until the PR is merged or closed. With a level, sets it; --default puts the PR back on the global level; with neither, says which level applies. Without a PR, lists the PRs with their own level. pr takes the same forms as alden review. See Follow-ups on PRs you reviewed.

Flag What it does
--off No notifications about this PR.
--rereview Only when you're asked to review it again.
--your-turn A re-review, or when every comment you left is resolved or answered.
--every-reply Each reply, resolve and re-review, and a push that makes one of your comments outdated.
--default Back to the global level.
--json Print the PR's level ({ pr, override?, level }), or the global level and the list, as JSON.

alden ui

Opens the queue and briefings in your browser, served on 127.0.0.1 only until you stop it. See Alden in your browser.

Flag What it does
--port <n> Serve on this port instead of a free one.
--no-open Print the link instead of opening a browser.
--json Print one JSON line with the link and port, and don't open a browser. The desktop app uses it, and it turns on background briefings.

alden mcp

Serves Alden to an AI coding tool (Claude Code, Cursor, Claude Desktop and others) as MCP tools over stdio, until the tool closes it. See Alden in your AI coding tool.

Flag What it does
--dir <path> The clone to review local changes and find callers in, instead of the folder it was started in.

alden doctor

Checks your setup here: the Alden version (and whether a newer one exists), where Alden keeps files, your settings, the GitHub sign-in and its scopes (and whether it can post the reviews you send), which of your organisations' PRs it can see (and why not, for any that hide them), the model and today's budget, whether this folder is a clone (and of which repo), and which languages the code graph reads in it. Every problem comes with its fix. --json prints the findings as data. Exits with 1 when something fails. With no model, its "Next:" line suggests alden setup as well as the first fix.

alden stats

Shows a repo's time to first review and review cycle time, before and after Alden, then your own time to review.

Flag What it does
--repo <owner/name> The repo (default: the one this clone's origin points at).
--days <n> Look at PRs opened in the last n days. Default 90.
--since <date> Compare before and after this date (YYYY-MM-DD), instead of your first use of Alden.
--horizon <days> Judge each wait over this many days. Default 14.
--refresh Ignore the hour-long cache.
--json Print the stats as JSON. Schema: packages/schema/json/repo-stats.v1.json.
--review-time Only your time to review, from this machine: no GitHub, no sign-in. With --json, schema packages/schema/json/review-time-stats.v1.json.

Time to review

How long your reviews take with Alden, from the review sessions it records on your machine (stats.reviewTime, on by default): for the reviews whose briefing you first opened in the last 14, 30 and 90 days, the median active time and the median time from opening the briefing to sending the review, with and without Alden's model, each with how many reviews it rests on.

Time to review · your reviews sent with Alden, by the day you first opened the briefing
                        Active      Open to send    Reviews
  Last 14 days
    With the model      12m         2h 10m          4 (few)
    Without             9m          50m             3 (few)

alden feedback

Shows how often you found Alden's flags useful, and what it missed, then where each lesson stands in every repo you've given feedback in ("2 of 3: one more not useful on API change flags and Alden will quieten them"). --json prints the summary only.

--export <file> writes your feedback to a file you can share. Repo names become a hash salted with a value that never leaves your machine (the same one usage stats use), and each flag's title becomes a code salted fresh for that export. Paths, lines and notes are dropped. PR numbers, check ids, verdicts, times and the model stay. Add --full to keep everything.

alden memory

Lists what Alden has learned about you in a repo, and your notes for it: by default the repo of the clone you're in, or --repo owner/name. --json prints the items. Every subcommand also takes --repo owner/name. See Learning and memory.

Command What it does
alden memory add <text> Adds a note; the model gets it with every review of the repo.
alden memory edit <id> <text> Changes a note's text.
alden memory exclude <id> <path> Stops applying a note to a folder (app/api) or file. alden memory lists where each note is stopped.
alden memory include <id> <path> Applies a note there again.
alden memory forget <id> Forgets a note or a learned item, by the id alden memory shows.
alden memory forget --all Forgets everything in this repo.
alden memory restore <id> Takes back a forget.
alden memory pause / resume Stops or restarts applying what Alden learned here. Your reactions are still saved, and notes still apply.

alden telemetry

Anonymous usage stats, off unless you say yes. alden telemetry says whether they're on; on and off change it (off also deletes anything not yet sent); show prints what's waiting to be sent. See Usage stats.

alden spend

Shows what Alden has spent on models today and over recent days, against your caps. --json prints the report as data. See Models, providers and budgets.

alden completion

alden completion zsh|bash|fish

Prints a tab-completion script for your shell, covering every command and flag. Install it with:

Shell Command
zsh alden completion zsh > "${fpath[1]}/_alden", then start a new shell. Or add eval "$(alden completion zsh)" to ~/.zshrc, after compinit.
bash alden completion bash > ~/.local/share/bash-completion/completions/alden. Or add eval "$(alden completion bash)" to ~/.bashrc.
fish alden completion fish > ~/.config/fish/completions/alden.fish

Run it again after upgrading Alden, so new commands and flags complete too.

alden config

Reads and changes settings. See Configuration.

Command What it does
alden config get <key> Prints a setting, e.g. alden config get model.name.
alden config set <key> <value> Changes a setting in your user config, e.g. alden config set budget.dailyUsd 20.
alden config unset <key> Removes a setting from your user config, so its default applies again, e.g. alden config unset model.effort.
alden config list Prints every setting after merging the defaults, your user config and the repo's config.
alden config path Prints the path of your user config file.