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:
- 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 modeldoes. 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 picksgpt-6.1-solunless you'd chosen an OpenAI model). - Use a local model. Looks for Ollama (at
OLLAMA_HOST, orhttp://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 setsmodel.provider,model.nameand, when Ollama isn't at its default address,model.baseUrl. - 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:
- The
ALDEN_GITHUB_TOKENenvironment variable. - The token Alden stored, in the OS keychain (or, where there's no keychain, a file only you can read).
- 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)
- A session starts the first time you open a PR's briefing anywhere (the web UI, the desktop app,
alden review, an AI tool'salden_review; a background briefing counts when you read it), and ends when you send the review from Alden. Reviewing the PR again later is a new session. One never sent within 14 days was abandoned. - Active, in the web UI and the desktop app: the time the PR's pane is visible and its window focused, leaving out any stretch over 2 minutes without a key, click, scroll or pointer move. From a terminal or AI tool, which can't tell: from its latest briefing there to the send, at most 30 minutes (the notes say how many reviews that is).
- With the model: Alden's model briefed the PR, or drafted for it ("Draft my review", "Draft with Alden").
- Reviews are grouped by the day you first opened the briefing, and counted only once that's 3 days ago, so quick
recent reviews don't crowd out slow ones not yet sent; open to send is capped at 3 days (
3d+). Briefings never sent from Alden aren't counted, and the notes say how many. - Under 10 reviews in a group is marked (few): one review can swing the median. The two medians are shown side by side, never as "faster": the reviews you use the model on aren't the same kind as the ones you don't.
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. |