npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aragon-agent/cli

v0.5.12

Published

AragonAgent CLI — a Claude-Code / Codex-style interactive terminal UI (TUI) on top of the @aragon-agent/core engine. Installable and runnable via npm / npx.

Readme

@aragon-agent/cli

A Claude-Code / Codex-style interactive terminal UI for the @aragon-agent/core engine. Type a task, watch the agent think and stream its answer, see each tool call render as a live card, and interrupt / steer / configure the session — all without leaving the terminal.

⚠️ Full permission, no sandbox. This first version runs at maximum permission: bash executes directly, file writes hit the real filesystem, and there is no per-action approval gate by default. Only run it in workspaces you trust. An opt-in confirmation mode is available via --confirm.

Install

# Global
npm i -g @aragon-agent/cli
aragon

# Zero-install
npx @aragon-agent/cli

Release note (R3): npx @aragon-agent/cli resolves @aragon-agent/core from the npm registry, so @aragon-agent/core@^0.1.0 must be published first (or bundled into the CLI dist). During local development inside this monorepo, npm workspaces link the local packages/core automatically.

Quick start

# Set a key (any one of these)
export ANTHROPIC_API_KEY=sk-ant-...
# ...or paste it live in the TUI via /settings, or pass --api-key

aragon                       # interactive TUI
aragon "summarize README.md" # interactive, auto-submitting the prompt
echo "list files" | aragon -p   # one-shot, prints to stdout then exits

Usage

aragon [prompt]                 Start the interactive TUI (or one-shot with -p / piped stdin)
aragon -p, --print [prompt]     Headless: stream the answer to stdout, then exit
aragon config                   Open the settings screen
aragon config set <key> <value> Non-interactive config write (e.g. model, provider)
aragon config path              Print the config file path
aragon models [--provider p]    List builtin + discovered models
aragon --version | -v           Print the version
aragon --help  | -h             Print help

Global flags

| Flag | Meaning | | --- | --- | | --provider <id> | anthropic | openai | google | | --model <id> | Model id | | --base-url <url> | Override the provider base URL (OpenAI-compatible endpoints) | | --api-key <key> | One-shot key override (not persisted) | | --thinking <level> | off\|minimal\|low\|medium\|high\|xhigh | | --max-tokens <n\|auto> | Output token cap: a number, or auto for the model's own ceiling (default 64000) | | --cwd <dir> | Working directory for tools | | --confirm | Confirm each mutating tool call | | --tool-timeout <ms> | Per-tool executor ceiling (default 180000) | | --idle-timeout <ms> | Watchdog idle timeout (auto-raised to ≥ tool-timeout + 30s) | | --theme <name> | auto\|warm\|cool\|light (dark is a compatibility alias for cool) | | --compact / --no-compact | Transcript density: no blank rows between turns, or the default | | --hints / --no-hints | Show or hide the composer hint row | | --show-thinking / --no-show-thinking | Draw the model's reasoning blocks in the transcript. Off by default — see What you see while it runs | | --live-tool-output / --no-live-tool-output | Show a bounded tail of a running command's output on its card. On by default — see What you see while it runs | | --fullscreen | Force the full-screen TUI, overriding the automatic downgrades | | --no-fullscreen | Force the inline renderer (the 0.2.0 behavior) | | --no-exit-transcript | Do not replay the session summary after exiting | | --plan / --no-plan | Start the session in PLAN mode (read-only research + review) or force BUILD | | --team / --no-team | Enable or disable team subagents. --no-team does not register the task tool at all | | --team-max <n> | Max subagents per dispatch for this run, clamped to [1, 10] | | --todo / --no-todo | Enable or disable todo planning. --no-todo does not register the todo_write tool at all | | --todo-panel / --no-todo-panel | Show or hide the right-hand todo rail. The tool stays registered either way | | --todo-follow <mode> | What happens when a run ends with steps left: notify (default), auto, off | | --retry / --no-retry | Retry a failed provider call with backoff (the default), or fail on the first error | | --retry-max <n> | Retries after the first attempt for this run, clamped to [0, 20]. 0 turns retry off | | --fast / --no-fast | Enable or disable the fast model tier. Off by default; see Fast model tier | | --fast-model <id> | The fast model id. Implies nothing about --fast on its own | | --fast-provider <id> | Provider for the fast model. Absent inherits the main provider | | --fast-review <n\|off> | Turns between automatic fast reviews, or off | | --no-skills | Disable the skill system entirely (no catalog, no skill tools) | | --skill <name> | Force-load a skill's full body for this run (repeatable) | | --skills-yes | Approve skill installs for this run (CI / headless) | | --transcript-retain <n> | Entries kept in memory, clamped to [200, 20000]. Older ones are dropped and counted | | --render-governor / --no-render-governor | Adapt the frame interval under load, or pin it at 33 ms | | --max-render-interval <ms> | Governor ceiling, clamped to [33, 1000]. 33 flattens the ladder | | --no-color | Disable ANSI color | | --quiet | (print mode) suppress tool/usage lines on stderr |

Exit codes: 0 success · 1 agent/runtime error · 2 config/usage error · 130 interrupted.

Slash commands (interactive)

| Command | Action | | --- | --- | | /help | Keybindings + command help | | /model | Open the model picker | | /settings | Open the settings screen | | /thinking <level> | Set the thinking level | | /max-tokens [<n>\|auto\|default] | Output token cap; with no argument, reports the setting and the effective cap for the live model | | /tools | List active tools | | /clear | Clear the visible transcript and the todo panel | | /reset | New conversation | | /cwd [dir] | Show / change the tool working directory | | /save [file] | Save the session to JSON | | /resume [file] | Load a saved session | | /plan [on\|off\|status] | Toggle plan mode - the keyboard-free equivalent of Shift+Tab | | /team [on\|off\|max <n>] | Team subagents: status and the live roster, the on/off switch, the fan-out width | | /todo [on\|off\|panel on\|off\|follow <mode>\|clear\|continue] | Todo planning: status, the on/off switch, the rail, follow-through, and picking an unfinished plan back up | | /retry [show\|on\|off\|max <n>] | API retry: the effective ladder, the on/off switch, the retry count. Takes effect in the running session, children included | | /fast [on\|off\|model <id>\|provider <id>\|same\|review <n\|off>\|delegate on\|off] | Fast model tier: status and this session's totals, the on/off switch, which model, the review cadence | | /update [status\|now\|skip\|off] | Auto-update: what is running, what is available, where it came from, when it looks again. now forces a check past the throttle; skip declines the offered version until a newer one appears | | /theme <auto\|warm\|cool\|light> | Switch the color theme live (persisted) | | /expand [n] | Expand / collapse the n-th-from-last (default last) tool card | | /copy | Copy the last answer to the clipboard | | /perf | What the renderer is doing: frame interval, mounted entries, dropped entries, cache occupancy. /perf reset clears the caches and the governor | | /logs | Show where this session is being logged, and at what level | | /reload | Re-read config.json after editing it in another window (refused mid-run) | | /skills [sub] | List and manage skills (see below) | | /<skill-name> [args] | Run an installed skill directly | | /exit (/quit) | Exit |

A leading / meant literally can be escaped as //. Typing / opens a command palette and @ opens a file-path completion popup — Tab / completes, Up / Down moves the selection, Esc closes it.

Keybindings

| Key | Action | | --- | --- | | Enter | Submit (idle) / queue a steering message (running) | | Alt+Enter / Shift+Enter | Insert a newline | | Shift+Tab | Toggle plan mode (BUILD <-> PLAN). Equivalent: /plan | | Esc | Abort the run / close an overlay / close a popup | | Ctrl+C ×2 | Exit (first press warns) | | Ctrl+L | Redraw the frame (clear the screen in inline mode) | | Ctrl+T | Show / hide thinking (off by default). In inline mode it applies to the live entry and everything drawn after it — settled entries are already in your terminal's scrollback and cannot be repainted | | Ctrl+O | Expand / collapse the most recent tool card — including its diff | | PgUp / PgDn | Scroll the transcript a page (full-screen mode) | | Shift+↑ / Shift+↓ | Scroll the transcript a line (full-screen mode) | | Mouse wheel | Scroll the transcript (or the open overlay) | | Shift+wheel | Scroll the transcript a page | | Home / End, Ctrl+A / Ctrl+E | Cursor to line start / end | | Alt/Ctrl+← / | Word-wise cursor jump | | Ctrl+W, Alt+Backspace | Delete the previous word | | Ctrl+U / Ctrl+K | Kill to line start / end | | Up / Down | Move between draft lines; recall prompt history at the edges | | ? | Open help (empty input) |

In full-screen mode the transcript is scrolled by the app itself: PgUp / PgDn and Shift+↑ / Shift+↓. While pinned to the bottom the viewport follows new output automatically; once you scroll away the status bar shows ↑N, a slim rail on the right edge shows where you are, and a hint counts the lines below you. Submitting a message always re-pins to the newest output. In inline mode (--no-fullscreen) history lives in your terminal's native scrollback, printed once via Ink <Static>.

The mouse wheel is a viewport gesture and nothing else. Wherever the pointer happens to be — including right on top of the composer — a notch scrolls the transcript three rows (a page with Shift), or scrolls the overlay when one is open. It never touches your draft, and it never recalls prompt history: that is / , and only / .

Two things follow from the app owning the mouse, and they are worth knowing before you meet them:

  • Selecting text now needs Shift+drag in most terminals. That is the terminal's convention for "an application is tracking the mouse", not something this CLI can opt out of while still reading wheel events.
  • tmux with mouse on keeps the wheel for itself, so the app never sees it. set -g mouse off hands it back.

Turn the whole thing off with --no-mouse, ARAGON_MOUSE=0, or aragon config set mouse false. With mouse support off the wheel simply does nothing in full-screen mode — it does not fall back to editing your draft, which is what it used to do. Inline mode is unaffected either way.

Themes

Three palettes plus auto:

| Name | Look | | --- | --- | | warm | Terracotta + amber over warm neutrals. The default (auto resolves here). | | cool | The blue/violet palette that shipped as dark through 0.3.x. | | light | For light terminal backgrounds. |

auto never guesses light: terminals cannot report their background reliably, and guessing wrong makes the app unreadable rather than merely wrong-looking.

Migrating from 0.3.xdark was renamed cool when warm became the default, and the old name still works everywhere: --theme dark, aragon config set theme dark, /theme dark, and a config file containing "theme": "dark" all resolve to cool, so a screen you explicitly chose does not change under you. The value is rewritten as cool the next time the config is saved. Only users who never picked a theme see the new default.

Density and hints are settable the same three ways: --compact / --no-hints for one run, aragon config set density compact / aragon config set hints false to persist. The composer hint row also shortens to ? help on its own after a few sessions — except while a run is in progress, when it always spells out esc abort in full.

What you see while it runs

Four rules, and each of them exists because the opposite was worse.

Reasoning is not shown. A model at thinkingLevel: high emits more chain-of-thought than answer, and it used to scroll the answer and the tool calls off the top of the screen. It is written for the model, not for you. So it is off by default, and a settled turn that thought leaves one muted row in its place:

  ✱ thought for 12s · ctrl+t to show

That row is the whole point — hiding information without saying that it exists is how a "clean" UI becomes a dishonest one. Ctrl+T shows the bodies for the session, showThinking: true (or --show-thinking, or ARAGON_SHOW_THINKING=1) shows them permanently, and /settings has a Show thinking row next to Thinking.

In inline mode (--no-fullscreen) the marker reads ✱ thought for 12s with no key hint, and the toast on Ctrl+T says Thinking shown for new output. Settled entries there have already been printed into your terminal's own scrollback, which cannot be repainted — so the key applies to the live entry and to everything drawn after it, and the row does not offer what it cannot deliver.

There is something to look at while it thinks. One row above the composer, for as long as a run is in flight:

  ⠋ Percolating…

The word rotates every four seconds. It carries no clock and no token count on purpose: the status bar one row below already has both, under the same condition, driven by the same ticker. Under reducedMotion the spinner is a static glyph and the word is chosen once and holds — rotating text is motion too. An idle frame is exactly what it was before this existed, down to the row count.

While a tool is in flight the row stops guessing and names it instead:

  ⠙ Running bash

running covers the whole turn, including the minutes the model is idle and a child process is doing the work. "Pondering" is right for the gap before the first token and simply untrue during a build.

A long command is not a blank card. bash is the only tool here that can run for minutes — npm test, a git clone, a training job — and while it ran, its card used to be one line of text that never changed. Now it shows the last eight lines of what the command is printing, plus one honest footer row:

  bash npm test   ⠹ running
  │  ✓ src/__tests__/patch.test.ts (49 tests)
  │  ✓ src/__tests__/diff-view.test.tsx (9 tests)
  │  (running)

and, when the child goes quiet, no output for 45s instead of a spinner that means nothing. A \r-driven progress bar — npm, pip, curl, docker — is one line rewritten a thousand times, and it renders as one row counting up in place, not a thousand rows of nearly the same string.

What the tail deliberately does not do. It is a display, not a transcript. ANSI colour, cursor motion and every other control byte are stripped, not interpreted (keeping colour would mean validating it, and an unterminated escape leaks into the rest of the frame; interpreting cursor motion would mean owning a screen buffer). It keeps eight rows, so Ctrl+O does nothing while a command is running — expansion is a promise about stored content, and there is no stored rest of a 400 MB stream to show. It is not saved: /save during a run writes no tail, because a resumed one would describe a process that died with the session. And it never reaches the model — at settle the card is replaced by the authoritative result, exactly as before. Set liveToolOutput: false (or --no-live-tool-output, or ARAGON_LIVE_TOOL_OUTPUT=0, or the Live output row in /settings) and the card is a single running row again, with no store allocated and no recorder attached.

A file modification looks like a file modification. write_file and edit_file now produce a real diff — hunks, line numbers, +N -M:

  +6 -5
  1163   top level of the file where the section never takes effect. It
  1164 - `applyFastConfigSet` (`:259`). A key missing from the list is
  1164 + `applyFastConfigSet` (`:252`). A key missing from the list is
  1165   `Unknown config key`; a key in the list but missing from the switch
  +13 lines (Ctrl+O)

Creating a 300-line file is the single most consequential thing an agent does, and it used to be reported as a byte count. Diffs collapse at 12 rows behind the existing Ctrl+O; there is no new keybinding.

This costs the model nothing — it saves. The structured patch reaches the screen on a CLI-local channel, not through the tool result, and the text the model reads gained a 4 000-character ceiling it did not have before. For a single-region edit that text is what it always was plus one @@ header; for a multi-region edit it is strictly smaller, because a change at line 40 and one at line 900 are now two small hunks instead of 860 removed rows followed by 860 near-identical added ones.

Full-screen mode

aragon takes over the terminal's alternate screen buffer — the mechanism vim, htop, and lazygit use. Two consequences worth knowing:

  • Your previous shell output is covered, not erased, and returns untouched when you exit. Nothing in your scrollback is destroyed.
  • The frame is fixed at rows - 1 tall, which is what keeps the composer and the status bar at the bottom of the screen even on an empty session.

On exit the session is replayed into the normal buffer as plain text so the conversation survives leaving the screen (--no-exit-transcript opts out; /save still exports the full JSON).

It downgrades to the inline renderer automatically when stdout is not a TTY, TERM=dumb, a CI environment variable is set, or the terminal is under 12 rows or 40 columns. --fullscreen overrides all of those except the non-TTY check — writing screen-control sequences into a pipe or a redirected file is never safe. --no-fullscreen, ARAGON_FULLSCREEN=0, or aragon config set fullscreen false opt out permanently.

The terminal's native scrollback and mouse wheel do not scroll the transcript in this mode, and mouse tracking is deliberately left off because enabling it costs text selection and copy in most terminals. If a crash ever strands your terminal on the alternate screen, reset restores it.

Render performance

A long session used to get slower and slower, and past a point it stopped responding at all. The cause was structural rather than incidental: Ink has no output caching, so every frame re-walked the whole mounted tree, re-measured every text node and re-serialised the frame. The cost was therefore proportional to every character the session had ever produced, not to the characters actually on screen — and transcriptWindow bounded the entry count, which is not the same thing when one entry can be fifty thousand lines.

Four things changed, and you should not have to think about any of them:

  • Off-screen entries are not mounted. The viewport renders the band you can see plus a couple of entries either side, and replaces the rest with two spacers of the right height. Scrolling and the ↑N readout are unchanged.
  • The expensive pure work is cached. Syntax highlighting and markdown parsing now run once per distinct block instead of once per frame. Themes are still applied at render time, so /theme takes effect immediately.
  • The transcript is bounded. A single answer cannot exceed 256 KiB in the view, and transcriptRetain caps how many entries are kept. Both bounds report what they removed rather than dropping it silently.
  • The frame interval adapts. If a frame is genuinely expensive, updates coalesce into a wider window — 33 ms up to a 320 ms ceiling — so the terminal stays responsive to typing and to Ctrl+C. A muted eco chip appears in the status bar whenever this is in effect: the stream getting chunkier is something you should be able to see a reason for.

/perf reports exactly what the renderer is doing:

render     rung 2  -  interval 80ms  -  last commit 61ms  -  eco
transcript 4213 entries  -  1000 retained  -  3213 dropped  -  38 mounted
heights    412 cached  -  6 estimated  -  cols 132
caches     md 178 (1.9MB)  -  hl 96 (1.4MB)  -  lines 340
mode       fullscreen  -  viewport 44 rows  -  offset 0

/perf reset clears the render caches and returns the governor to its fastest rung. --no-render-governor (or renderGovernor: false, or ARAGON_RENDER_GOVERNOR=0) turns the adaptation off entirely; the output is identical, just heavier under load.

Inline mode (--no-fullscreen, TERM=dumb, CI, a very small terminal) gets one extra guarantee. Ink repaints the entire session history on every frame once a live entry grows taller than the terminal, which is a genuine freeze rather than a slowdown. The live region is now clamped to stay below that threshold, with a ... N earlier lines marker naming what is deferred; the entry prints in full into your scrollback the moment it finishes.

Plan mode

aragon has two postures, and Shift+Tab switches between them. /plan does the same thing for terminals that swallow the key (see below).

| Mode | What it means | | --- | --- | | BUILD | The default, and unchanged from earlier versions: you ask, the agent does it. | | PLAN | Research and design only. The agent reads, asks you the decisions it cannot settle by reading, and submits a plan for approval before anything is written. |

BUILD is right for "rename this symbol". PLAN is right for "add multi-tenant support" — anything where you want to see and steer the approach before a single byte changes.

What plan mode actually stops

In PLAN, five tools are refused at the tool boundary: write_file, edit_file, bash, skill_install and skill_create. That is a property of the wiring, not a promise in a prompt — the refusal happens before the tool runs, so the badge is telling you something that is structurally true.

bash is refused in full, git status included. This is the most likely question this feature generates, so: there is no reliable way to classify a shell string as read-only, and a gate that is right 95 % of the time is worse than one that is always right, because you stop trusting the badge. Use read_file, list_dir, glob and grep, which stay available; the refusal message names them so the agent has somewhere to go. There is no allowlist and there will not be one built out of substring matching.

Everything else still works: reading, searching, loading skills, and asking you questions.

The two plan-mode tools

  • ask_user renders a keyboard-driven wizard: 1–5 questions, 2–4 options each, exactly one marked RECOMMENDED, plus an Other… free-text option. / choose, Enter confirms and advances, goes back, Esc cancels. Pressing Enter through the whole wizard accepts every recommendation, which is a deliberate "use your judgement" path rather than an accident. A last screen lets you review before submitting.
  • submit_plan renders the plan as a scrollable card: a approves, r opens a one-line feedback field (Enter sends it, goes back to the card), Esc dismisses. Approving flips the session to BUILD immediately and the same run continues straight into implementation — you do not have to re-ask.

Cancelling either one is not an error. The agent is told to proceed on stated assumptions rather than to retry.

Dismissing a plan is not how you stop. Esc on a plan card asks for a better plan — the agent is told to refine it and submit again — so a model that keeps submitting keeps getting cards. To stop the run itself, press Esc twice: the first closes the card, the second aborts the run. Ctrl+C twice still exits the session outright.

Where the mode is shown

The status bar always names a non-default mode (PLAN, or PLAN → BUILD while a switch is pending), including on short terminals, with --no-hints, and in inline mode. The composer additionally shows a PLAN chip on its hint row and tints its border, where there is room for it.

Switching mid-run

Tightening applies at once; loosening waits. Pressing Shift+Tab toward PLAN during a run takes effect immediately — you pressed it because the agent is about to do something. Pressing it toward BUILD during a run is deferred to the end of the run, so a session you launched under a read-only guarantee cannot start writing files because of one stray keypress. The status bar shows PLAN → BUILD while that is pending. Approving a plan is the one exception, and it is an informed act rather than a stray keypress.

If Shift+Tab does nothing

Some multiplexers and remote-desktop stacks never send CSI Z. /plan, /plan on, /plan off and /plan status are first-class equivalents, and --plan / ARAGON_PLAN=1 / planModeDefault cover the startup case.

Headless

aragon -p --plan "add SSO" is a useful combination: the read-only gate still applies, so it means "tell me how you would do this, and do not touch my repository". No question or plan tool is registered there — there is nobody to ask — and the agent writes the finished plan as its final message in markdown.

TODO planning

For work with three or more distinct steps the agent keeps a visible plan: it writes a checklist with the todo_write tool, marks exactly one item as in progress, and ticks it off before starting the next. In full-screen mode that list is rendered as a right-hand rail, about a fifth of the terminal wide.

  transcript ...                            | TODO             2/7
                                            | ####------
                                            |
                                            | v  1 Read the reducer
                                            | v  2 Design the store
                                            | >  3 Wiring the rail into
                                            |      AppShell
                                            | o  4 Add the panel-rows test
                                            | o  5 Update the README
                                            |      +2 more

Ask for something small and nothing appears. The agent is told, in its system prompt, not to use the tool for anything it can finish in one or two steps, for a question, or for a search with no work attached — and a one-item list against an empty plan is refused outright. A session that never plans has byte-identical layout to a build without this feature.

The list is a projection of what the model believes, so nothing that does not also tell the model may change it — except you, saying so:

  • /clear and /todo clear take the plan off the screen. Neither touches the conversation, so the model still knows what it was doing and its next update brings the panel straight back.
  • /reset clears the conversation, so the plan goes with it.
  • /save writes the list and /resume restores it. Resuming a session that has no list clears the current one, rather than leaving a plan on screen whose conversation has just been replaced.
  • A finished plan is dropped at the START of your next message, so you still get to see 7/7 done. An unfinished one survives "continue" / "now do the rest", and is dropped after three unrelated turns rather than holding a fifth of the screen for the rest of the session.

When a run ends with steps left

By default you get a notice and /todo continue — nothing auto-continues on your behalf. /todo continue no longer says "continue the remaining items"; it sends the model the numbered list of steps that are still open, so a plan that scrolled out of the context window some turns ago is still followed exactly.

/todo follow auto (or --todo-follow auto, or todo.followThrough in config.json) turns that into an actual loop: the CLI announces Continuing with 4 remaining steps in 3s - Esc to stop., waits, and then sends the continuation itself. Two structural limits bound it, and neither is a setting:

  • A continuation that completes no step buys exactly one more attempt. After that you get a sentence and the keyboard back.
  • A single plan is continued at most 25 times however productive it looks. A re-plan forgives the first counter but never the second, so a model that reshapes its list every turn cannot lift the ceiling.

Esc during the grace window cancels; so does typing anything. A run that ended with an error never auto-continues in any mode — you get a warning instead. A run you aborted with Esc now says nothing at all, where it used to report what you had just interrupted.

/todo follow off is the third mode: no notice, no continuation, silence.

Under -p there is no grace window (there is nobody there to use it), so the two counters are the whole of the protection. [todo] continuing (3 steps left) goes to stderr before each continuation and [todo] 3 steps unfinished when it stops; both are suppressed by --quiet, and an unfinished plan never changes the exit code.

Inline mode

Inline mode has no fixed frame and therefore no rail, but it does get a one-row plan strip under the transcript:

todo 3/7  >  Adding the rail to AppShell                        +2 done

It never wraps and never grows past one row, so the composer does not move. The +N done suffix drops below 80 columns and the counter compacts to [3/7] below 100, matching the status bar. --no-todo-panel hides the strip as well as the rail.

/todo reports status and switches things off: /todo off unregisters nothing (the tool list is fixed when the session starts) but stops the tool working and drops the guidance from the system prompt, while /todo panel off keeps the planning discipline and hides the column — which is what you want with a screen reader, and what --no-todo-panel does for a whole session. Under -p the plan is written to stderr as [todo] 3/7 <step> lines, suppressed by --quiet.

The rail is not mounted below 80 columns, while an overlay is open, in inline mode, or when the viewport is too short to say anything useful; the transcript keeps at least 62 columns at every width. In those cases the counter appears in the status bar instead, and the checklist is still written into the transcript as one card per turn.

Built-in tools

read_file, write_file, edit_file, list_dir, glob, grep, bash — all at full permission. Paths resolve against the session working directory. The per-tool timeout and 100 KB output truncation are enforced by the core executor; bash's timeout param only shrinks within that ceiling.

When skills are enabled, four more are added — the two read tools skill and skill_find, then the two mutating ones skill_install and skill_create (see below). --no-skills removes them again. Updating a skill is deliberately not among them; that is a aragon skills update decision for you, not the model.

With team mode on — which is the default — one more is added: task, the delegation tool (see below). --no-team removes it again.

With todo planning on — also the default — one more is added: todo_write, the planning tool (see above). --no-todo removes it again.

Team subagents

The agent can hand parts of a job to short-lived subagents that run in parallel, then read one combined report of what they each found. It decides for itself whether to delegate; a session that never calls task is the session that existed before this feature.

> read the auth middleware, map the route table, and check the migration

 ◆ team  2 running · 1 done · 84s                             ✉ 1
 ⠋ a1  read the auth middleware      tool: grep         22.1s
 ⠙ a2  map the route table           thinking           31.6s
 ✔ a3  check the migration           done  4 turns      18.2s

What a subagent is. A full agent with its own message history, the same tools and the same working directory — but no memory of your conversation, so its brief has to be self-contained. It cannot delegate further (depth is capped at one by construction) and it cannot ask you anything.

Delegate wide, not deep. Two to four subagents is the usual size. The default cap is 5 per dispatch and 3 in flight at once; the hard maximum is 10 and no config file can raise it. maxConcurrent is separate from maxSubagents on purpose: five simultaneous streams against one API key is a reliable way to collect rate-limit errors, and each one would land in the report as a failed subagent.

The report. One text result: a header with the ok/failed counts, aggregate tokens and cost, then one section per subagent with its status, timing, the files it wrote and its own final summary. A failed subagent never fails the dispatch — partial results are the normal outcome of a fan-out. When two subagents wrote the same file the header says so, phrased as a warning rather than a fact: the file list is derived from write_file / edit_file, so a write made through bash is invisible to it.

Talking to each other. Subagents get two extra tools, team_send and team_wait. Messages are delivered by attaching them to the recipient's next tool result, so nobody has to poll and nobody's work is interrupted. The limits are the point rather than an afterthought: 6 messages per subagent, one every 15 seconds, 24 per dispatch, a broadcast costing two. Every refusal is a plain result naming the limit, never an error — an error reads as a malfunction and invites a retry, which is the behaviour the limits exist to prevent.

What you see. While a dispatch runs, the roster above sits between the transcript and the composer and the status bar carries agents 3/5 ([3] under 100 columns). Both disappear when it finishes and the transcript keeps a card with the per-agent results; Ctrl+O expands it to their summaries. Under -p the same transitions go to stderr as [team] a1 ok 22.1s 7 tools lines, and the children's tokens are folded into the [usage] footer.

Interaction with the other subsystems.

  • Plan mode reaches one level down. In PLAN, every subagent is built with the same read-only gate, so write_file / edit_file / bash are refused inside them too. Parallel research is plan mode's best use, so task itself is allowed. A single subagent can be pinned read-only with readOnly: true even in a BUILD session — the field can only ever tighten.
  • A skill's allowed-tools ceiling reaches one level down too, so delegating is not a way around it. Subagents get skill_find but not skill: loading a skill mutates a turn-scoped registry the lead owns, and three subagents doing it at once would narrow what the lead may do next in a way nothing would report. Always-on skills still reach them.
  • --confirm queues subagent confirmations one at a time, labelled with the subagent that is asking ([a2] Write: src/routes.ts).
  • Logs. dispatch_start and dispatch_end are recorded at info with the ok / failed / aborted counts and aggregate usage; phase transitions at debug. A team_send subject is recorded, never its body; a subagent's brief and summary only at trace.

Esc aborts the whole dispatch — every subagent within a couple of seconds — and the report comes back marked ABORTED with whatever was finished.

Fast model tier

A second, cheaper model can be made a first-class citizen of a session. It is off by default — with fast.enabled: false the system prompt, the task tool schema, the transcript and the request payloads are exactly what they were before this feature existed — and it buys you two things once you turn it on.

Delegation (the agent decides). task gains one optional field per subagent, model: "fast". A child marked that way runs on the fast model and is otherwise identical: same tools, same working directory, same --confirm gate, same plan-mode gate, same skills ceiling. Delegating to a cheaper model is a model choice, never a permission boundary. This is where "not complicated, but very expensive in context" is actually paid for: a child that reads nine files and reports four sentences moves ~200 KB of file bodies out of the lead's window and onto a model that costs a fraction as much per token.

Periodic review (the harness decides). Every N completed turns, a small digest of what the lead has been doing goes to the fast model with one question — is this still on track? — and if the answer is not "on track" it is injected back into the running loop as a <fast_review> block. The lead sees a short second opinion mid-run, when it can still act on it, for a few hundred tokens instead of a second full-size turn.

> refactor the config loader and keep the tests green

  fast review #2 · claude-haiku-4-5 · turn 12 · 1.4s
  You have edited config/schema.ts three times without running the tests.
  The clamp for reviewEveryTurns is missing its upper bound.

The digest is bounded, and that is the whole economic argument. The reviewer keeps its own ring of recent turns — the tools you called, whether they failed, the tail of what the model said — and never reads the message history. Sending that history to the "cheap" model would make a review cost more than the turn it is reviewing.

Cost is attributed per tier. A fast-tier subagent's tokens are priced at the fast model's table, not the lead's, and the dispatch report states the two separately. If the fast model is not in the built-in price table the number is shown as unknown rather than as $0.00 — a feature that looks free while it is spending money is worse than one that admits it does not know.

The review has a session budget, and delegation deliberately does not. A session is not one run — it is one run per message you send — so a cadence alone bounds nothing over a working afternoon. fast.reviewMaxPerSession (default 40) is the total number of reviews a session may start; reaching it prints one info notice naming the remedy, and /fast status reads 12/40 from the first review rather than a bare count you can only size afterwards. Raise it live with /fast budget 80. The budget is denominated in reviews, not currency, because the fast tier is precisely where a model the price table has never seen lives — a dollar ceiling would silently never fire for the configuration that most needs one. Delegation is never budgeted: it is spend the lead chose in service of a message you sent, it is already bounded by team.*, and it exists to reduce total cost.

Turning it on

aragon config set fast.model claude-haiku-4-5
aragon config set fast.enabled true

or, in a session: /fast model claude-haiku-4-5 then /fast on. Either way the tier is on for the next launch; /fast on in a session that started without it saves the setting and says so, because the task schema is fixed at startup and cannot grow a field mid-session.

| key | default | meaning | |---|---|---| | fast.enabled | false | Resolve the tier at all. | | fast.provider | '' | Empty inherits the main provider. | | fast.model | '' | The fast model id. Empty means not configured — it never falls back to the main model, so "same as main" stays distinguishable from a typo. | | fast.baseUrl | '' | Empty inherits the session's base URL only when the provider matches. | | fast.thinkingLevel | 'off' | Applied to fast children and to reviews. | | fast.delegate | true | Allow model:"fast" on task. | | fast.review | true | Run the periodic review. | | fast.reviewEveryTurns | 5 | Turns between reviews (1–50). | | fast.reviewContextTurns | 3 | Turns included in one digest (1–10). | | fast.reviewMaxChars | 280 | Ceiling on an injected critique (80–600). | | fast.reviewMaxPerSession | 40 | Reviews started per session, across all runs (1–500). There is no "unlimited" sentinel. |

Flags: --fast / --no-fast, --fast-model <id>, --fast-provider <id>, --fast-review <n|off>. Environment: ARAGON_FAST, ARAGON_FAST_PROVIDER, ARAGON_FAST_MODEL, ARAGON_FAST_BASE_URL — the four that a container or a wrapper owning argv cannot otherwise reach. There is deliberately no env var for the review cadence: tuning it is what the config file is for.

/fast is the discoverable surface and /fast status is the guaranteed reporting one:

/fast                      status, the resolved model, the cadence, session totals
/fast on | off             live switch
/fast model <id>           accepts provider:model
/fast provider <id>
/fast same                 run the fast tier on the main model
/fast review <n> | off
/fast budget [n]           the session review budget; bare form reads it
/fast delegate on | off

/fast budget with no argument is a read, so it is answerable while a task dispatch is running; /fast budget <n> is a write and is refused mid-dispatch like every other /fast setting.

What you see. A fast chip in the status bar's right cluster while the tier is live (fast* while a review is in flight, dropped below 100 columns), a one-line card per review in the transcript, and n fast plus a trailing ~ on fast children in the team roster. /fast status reports the session totals the status bar cannot: reviews run, children delegated, tokens and cost. Under -p nothing extra is written to stdout or stderr — the review spend is folded into the [usage] footer and the reviews are in the log.

When the tier stops resolving. fast.provider: '' inherits from the main provider, so switching model or clearing a key can leave the tier unusable mid-session. When that happens model:"fast" is downgraded to the main model, the downgrade is counted and stated in the dispatch report, and one notice names the reason. A silent downgrade would leave the agent believing its cost model while paying full price.

When the review fails. Three consecutive misconfiguration failures (a wrong model id, a dead gateway, a key with no access) disable the reviewer for the session with exactly one warning. A busy provider — rate-limited or overloaded — is treated as transient and never counts, because that condition fixes itself and a session-long silent shutdown over it would not. A review that you cancelled — Esc, a run that ended first, quitting — is neither: it leaves a cancelled card and no strike.

The review fails fast, and your own work does not. The reviewer calls through its own provider registry with one retry — not the ten retry.maxRetries defaults to for the lead — and it does not observe retry.* or /retry at all. That policy is a statement about how hard to fight for your answer; inheriting it for a background advisory is how an unrequested call ends up competing with you for a rate-limited provider's quota. The review's own wall-clock bound is 20 s.

Skills

A skill is a reusable expert procedure stored on disk: a directory containing a SKILL.md (YAML frontmatter + Markdown body) and, optionally, reference/, scripts/ and assets/. The format matches Claude Code's, so an existing community skill directory works as-is.

Progressive disclosure

This is the part that makes skills cheap enough to install a lot of:

| Level | What the model gets | When | | --- | --- | --- | | 1 | Name, scope, and a one-line "what + when" | Always, in the system prompt. Whole catalog capped at 6 000 bytes. | | 2 | The full SKILL.md body + a list of bundled files | Only when the model calls skill(name=…) | | 3 | The bundled files themselves | Only when it reads them with read_file / bash |

A skill costs a line in the prompt rather than its whole body, so installing many of them stays cheap. The model decides on its own whether a task matches a skill — you do not have to name one.

At Level 2 the file list is split into what to read and what to run, and carries the skill's absolute root so the model can build real paths. The accompanying guidance is platform-specific: on Windows the bash tool runs cmd.exe, so the model is told to run .py with python <abs path> and that a .sh file will not work — rather than the previous, flatly untrue "run scripts with bash". aragon skills doctor warns when a skill bundles only scripts for the other shell.

How many fit in Level 1 depends on your descriptions, and on the language they are written in. The 6 000-byte ceiling is measured in UTF-8 bytes: a terse English description costs roughly 180 bytes a line (~30 skills), while a Chinese one at the 220-character cap can cost 660 (~10 skills). Past that point the catalog truncates.

Truncation is not a dead end. Entries are ranked before it happens, and what falls off is still reachable:

  • Ranking: scope first (env > project > user > bundled), then how recently and how often you have actually used each skill. A skill you ran an hour ago outranks one you have never used, so what survives truncation is what you actually work with — not whatever sorts first alphabetically.
  • skill_find: when the catalog does truncate, it says so and names this tool, which searches everything installed by name, description and keyword. It only ever searches what is already on this machine — it never reaches the network and never suggests something to install.

Both are off the critical path: with no usage data recorded the order is exactly the plain scope-then-name order, and skill_find is only advertised in the prompt when something was actually omitted.

Using them

aragon skills list [--sort=recent]          # what is installed
aragon skills info <name>                   # version, path, provenance, files
aragon skills install <source> [--yes]      # dir | git repo | https .md / .zip
aragon skills install github:owner/repo#v1.2.0
aragon skills update <name> [--yes] [--force] [--dry-run]
aragon skills update --all [--yes]          # every skill that has an upstream
aragon skills update --check [<name>|--all] # is there a newer version?
aragon skills remove <name> [--yes]
aragon skills create <name> --description "what + when" [--yes]
aragon skills path                          # user skills directory
aragon skills doctor                        # validate + detect tampering
aragon skills usage [--json]                # local use counters
aragon skills usage --reset --yes           # delete them
aragon skills trust <dir>                   # allow a project skills directory

Updating

update re-fetches a skill from the source recorded in its install manifest, keeping installedAt and recording updatedAt + previousVersion.

  • Local edits are protected. If you have changed an installed skill, update refuses and names the files, before downloading anything. --force overwrites them — and --force discards your edits; copy them out first. The replaced directory is parked under the staging trash, so a mistake is recoverable by hand.
  • The host allowlist is re-checked against your current skills.allowedHosts, not the one in force when you installed. Narrowing that list therefore also constrains updates.
  • --all never stops on one failure. Skills that cannot be updated (hand-authored, bundled, or locally modified) are reported as skipped, which is not an error; only a genuine I/O or validation failure exits non-zero.
  • --check reports unknown freely. It compares the commit recorded at install time against git ls-remote, so it can only answer for git sources installed by a version that records one. Anything else is honestly reported as unknown rather than guessed.
  • The model cannot call update. Installing is something you pointed it at; swapping working instructions for different ones is a maintenance decision and stays with you.

Interactively the same lives under /skills … (/skills update <name> [--force], /skills update --all, /skills list --sort=recent, /skills policy [mode], /skills unload, /skills usage [--reset]). Every usable skill also becomes a slash command:

/pdf-forms invoice.pdf --flatten

Both delivery paths share skills.bodyMaxBytes, so an oversized SKILL.md is truncated with a visible marker rather than submitted whole. Loading the same skill twice in one conversation returns a short digest (description, file list, guidance) instead of a second copy of the body; the model can ask for the full text back with skill(name="…", force=true).

Bodies may use $ARGUMENTS and $1..$9; $$ is a literal $. If a skill declares no placeholder, the arguments are appended under an ## Arguments heading instead. Where a skill's name collides with a built-in command, the built-in wins and the skill is reachable as /skill:<name>.

Where skills come from

Four scopes, later ones overriding earlier ones by name:

| Scope | Location | Writable | | --- | --- | --- | | bundled | <package>/skills/ | no | | user | aragon skills path | yes — the default install target | | project | <cwd>/.aragon/skills/ | yes | | project | <cwd>/.claude/skills/ | no — read-only Claude Code interop | | env | ARAGON_SKILLS_PATH (:/;-separated) | no |

A shadowed skill is not lost: /skills shows it as ~shadowed by <scope>.

Frontmatter

---
name: pdf-forms          # required, kebab-case, ≤ 64 chars
description: Fill, flatten and validate AcroForm PDFs. Use when the task
  mentions PDF forms, field filling, or flattening a fillable PDF.
version: 1.2.0
license: MIT
author: Jane Doe
homepage: https://github.com/jane/pdf-forms
keywords: [pdf, forms]
allowed-tools: [read_file, bash]   # enforced as a per-turn tool ceiling (union)
activation: auto                   # auto | always | manual
---

description is the only text a model sees before deciding to load the skill, so it has to say both what the skill does and when to use it. Unknown keys are preserved, so a newer Claude Code field will not break parsing.

activation: always injects the body into every session's system prompt (12 000 bytes total across all such skills); manual keeps it out of the catalog so it runs only when explicitly invoked.

Security model — and its limits

Be clear about what this does and does not buy you:

  • Installing requires a human. The approval gate checks whether a person is actually reachable before asking, and refuses when nobody is. Under -p there is no TUI and therefore no approver, so skill_install fails with an actionable message instead of writing to disk unattended. Opt out deliberately with --skills-yes or skills.requireApproval=false.

  • Project directories need trusting once. Cloning an unfamiliar repository does not grant it the right to inject instructions into your session.

  • Nothing is executed at install time. No postinstall, no dependency install; the executable bit is not preserved. Scripts run only when the model invokes bash.

  • Archives are gated on real bytes — total size, per-entry size, compression ratio and entry count, all abortable mid-extraction. Path traversal, absolute paths, symlinks and Windows device names are refused.

  • Git is never run through a shell, and ref / owner / repo fragments are whitelisted and refused if they start with -.

  • Third-party text cannot break out of its prompt block: angle brackets in descriptions, bodies and file names are neutralized before rendering.

  • A changed SKILL.md is noticed at load time. Every install records a sha256; discovery re-checks the one file that reaches the model's context and flags it as !modified if it no longer matches what you approved. See skills.integrity below.

  • Concurrent installs cannot corrupt a skill. Writes take a per-directory advisory lock, so two aragon processes installing at once queue instead of interleaving their atomic-replace steps. Limit: the lock relies on exclusive file creation, which is not reliably atomic on every NFS implementation. It self-expires after 60 seconds and waits at most 5, so the worst case there is no mutual exclusion — never a hang.

What it does not do: there is no sandbox. Approval blocks silent installation; it does not make a skill you approved safe. A skill you accept can contain adversarial instructions, and its scripts run with your full user permissions — the same trust model as pasting text into the prompt and the same as the bash tool. /skills info records provenance and a sha256 per file so you can audit what arrived and notice if it changed. The integrity check answers "is this still the file I approved?", not "is this file from someone I trust" — there is no signing and no key distribution.

allowed-tools is enforced now (see below), but read the next section before treating it as a permission boundary: it is blast-radius control, not a security boundary, and a skill can widen its own ceiling by loading another skill.

The tool ceiling (allowed-tools)

A skill that declares allowed-tools constrains which tools the model may use for the rest of the current turn:

allowed-tools: [read_file, write_file]
  • Scope is one turn. The ceiling appears when a skill is loaded — by the model calling skill(...), or by you running /<skill-name> — and it is gone as soon as you send the next message. A skill you used this morning does not restrict unrelated work this afternoon.
  • Read-only tools are always allowed, declared or not: read_file, list_dir, glob, grep, plus skill and skill_find. What the declaration actually controls is the five tools that change something — write_file, edit_file, bash, skill_install, skill_create.
  • Claude Code names work. [Read, Bash, MultiEdit] maps onto this host's read_file / bash / edit_file. Tools that exist there but not here (WebFetch, Task, TodoWrite, …) are ignored rather than treated as errors.
  • A name we cannot resolve waives the whole declaration, and says so. One typo means that skill imposes no ceiling at all — never a narrower one you did not write. aragon skills doctor reports these up front.
  • activation: always skills never impose a ceiling. They are ambient reference material, not a procedure you chose to run.

Three modes, via skills.toolPolicy (default enforce), aragon --skill-tool-policy <mode> for one run, or /skills policy <mode> for the current session (which takes effect immediately, even mid-turn):

| Mode | Behaviour | | --- | --- | | enforce | The call is refused; the model is told what it may use instead. | | warn | The call runs, and you get one notice per tool per turn. | | off | No ceiling, and nothing about allowed-tools reaches the model. |

/skills unload drops the ceiling for the current turn. It does not remove skill text already in the conversation — nothing can.

What this is and is not. It is blast-radius control, not a security boundary. The declaration is written by the skill's own author, so a malicious skill can simply declare [bash]. Its value is that a declaration is now binding: you can read one in /skills info and decide whether to install, and an honest author's [read_file] means a "while you're there, run rm -rf" line smuggled into that skill's text — or into a file it tells the model to read — cannot execute.

And a known limit: the ceiling is a union across every skill loaded this turn, and skill is always available. So a skill can widen its own ceiling by instructing the model to load a second, more permissive skill. This is not blocked — blocking it would either strand the model inside a skill it cannot escape, or break every multi-skill workflow — but every widening is printed to the transcript:

Tool ceiling widened by skill "skill-creator": +write_file, +skill_create

So it stops the smuggled instruction; it does not stop a skill that deliberately teaches the model to reach for another one.

Usage counters

To rank the catalog, the CLI keeps a small file next to your skills directory:

// <aragon skills path>/../skill-usage.json
{ "schema": 1, "skills": { "deploy-preview": { "useCount": 12, "lastUsedAt": 1785050000000 } } }

It contains the skill name, a count, and a timestamp. Nothing else — no arguments, no conversation content, no working directory, no machine identifier. It is never transmitted anywhere, by anything. Delete it whenever you like; the only effect is that the catalog falls back to plain scope-then-name order. Set skills.usageTracking=false to switch it off entirely, after which the file is neither read nor written.

Automatically injected activation: always skills are deliberately not counted — they load on every turn, so counting them would say nothing about what you actually use.

Configuration

Config is layered (highest priority last): defaults → user config file → env / .env → CLI flags.

  • Env / .env: ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY / GEMINI_API_KEY, plus ARAGON_PROVIDER, ARAGON_MODEL, ARAGON_BASE_URL, ARAGON_THINKING, ARAGON_SHOW_THINKING (1 shows reasoning blocks), ARAGON_LIVE_TOOL_OUTPUT (0 keeps a running tool card to one line), ARAGON_MAX_TOKENS (a number, or auto / 0 for the per-model ceiling), ARAGON_THEME, ARAGON_FULLSCREEN, ARAGON_PLAN (1 starts in plan mode), ARAGON_TEAM (0 disables team subagents), ARAGON_TEAM_MAX (fan-out width), ARAGON_TODO (0 disables todo planning entirely), ARAGON_TODO_FOLLOW (notify / auto / off), ARAGON_RETRY (0 disables API retry), ARAGON_RETRY_MAX (retry count; 0 also disables), ARAGON_UPDATE (0 / off disables auto-update, notify reports without installing), ARAGON_UPDATE_REGISTRY (registry base URL for the update check), ARAGON_SKILLS (0 disables), ARAGON_SKILLS_PATH, ARAGON_SKILLS_DISABLED (comma-separated names), ARAGON_LOG_LEVEL, ARAGON_LOG_FILE (0 disables), ARAGON_LOG_DIR, ARAGON_TRANSCRIPT_RETAIN, ARAGON_RENDER_GOVERNOR (0 disables), ARAGON_MAX_RENDER_INTERVAL_MS. ARAGON_HOME is the exception that cannot come from .env: it is read before any .env is loaded. See Files & logs.
  • User config file (aragon config path): JSON, written 0600 on POSIX. Holds provider / model / keys and your preferences, and nothing else — the prompts you type and the counters behind one-time notices live in their own files (see Files & logs). Keys are masked in the UI and never logged. It lives in your home directory — see Files & logs — and editing it by hand is supported: aragon config edit opens it, and an invalid edit is reported rather than silently resetting every setting.

| Config key | Default | Meaning | | --- | --- | --- | | maxTokens | 64000 | Output token cap, clamped to [256, 200000]. null means auto — use each model's own ceiling, never above 64000. Absent means the default. See Output token limits. | | showThinking | false | Draw the reasoning the model returns. thinkingLevel is the effort the provider is asked to spend; this is whether the terminal shows it. Off by default: a settled turn that thought leaves one muted thought for 12s row in its place, so nothing is hidden silently. | | liveToolOutput | true | Draw up to eight sanitised rows of a running tool's output on its card, plus a no output for Ns row when the child goes quiet. On by default, unlike showThinking: this ADDS the information a long bash call otherwise hides, and its cost is bounded by construction — eight rows per call, sixteen calls, whatever the command emits. Turn it off and the card is a single running row again, with no store allocated and no recorder attached. | | fullscreen | true | Use the full-screen TUI (still subject to the automatic downgrades). Setting it to false opts out permanently; leaving it true is not a force — only --fullscreen / ARAGON_FULLSCREEN=1 override the heuristics. | | exitTranscript | true | Replay a plain-text session summary after exiting (full-screen only). | | transcriptWindow | 1000 | How far back you can scroll, clamped to [50, 20000]. Entries beyond it collapse into one line. It is no longer a rendering budget: the viewport is virtualised, so off-screen entries are not laid out at all. | | transcriptRetain | 1000 | Entries kept in memory, clamped to [200, 20000] and raised to transcriptWindow if the two conflict — with a startup notice saying so, because retaining less than you can scroll to would otherwise make part of the horizon quietly unreachable. Older entries are dropped, counted, and reported by /perf and by the exit replay. | | renderGovernor | true | Widen the streaming frame interval when a frame is genuinely expensive. See Render performance. | | maxRenderIntervalMs | 320 | Ceiling of the governor ladder, clamped to [33, 1000]. 33 flattens it to the pre-0.6 cadence without disabling the mechanism. | | planModeDefault | false | Start every session in plan mode. --no-plan still overrides it for a single run. | | planModeMaxAskRounds | 4 | ask_user rounds allowed per user message, clamped to [1, 10]. The counter resets on your next message; steering does not reset it. | | planModeHumanTimeoutMs | 1800000 | Ceiling on a single question / plan wait, clamped to [60000, 7200000]. Thirty minutes is far outside "went to get coffee", but a ceiling has to exist so an unattended terminal cannot wedge a CI job forever. | | historyEnabled | true | Record submitted prompts to prompt-history.jsonl for recall. Setting it to false stops new writes; it does not delete what is already stored (that is aragon history clear --yes) and does not stop reading. See Prompt history. | | team.enabled | true | Master switch for team subagents. false means the task tool is never registered — /team on in such a session saves the setting for next launch and says so, rather than advertising a tool that is not there. | | team.maxSubagents | 5 | Subagents per dispatch, clamped to [1, 10]. The 10 is the hard ceiling and is enforced twice — on the config value and again on what the model asks for — so hand-editing this file cannot raise it. | | team.maxConcurrent | 3 | Subagents in flight at once, clamped to [1, 10] and capped at maxSubagents. A separate knob because provider rate limits are a different constraint from context economics. | | team.subagentTimeoutMs | 300000 | One subagent's wall clock before it is aborted, clamped to [30000, 1800000]. A wedged subagent dies on its own ceiling without taking the dispatch with it. | | team.dispatchTimeoutMs | 900000 | The whole dispatch's wall clock, clamped to [60000, 3600000]. | | team.maxTurnsPerSubagent | 24 | Runaway-loop cap, clamped to [4, 100]. A subagent stopped here is reported as stopped: turn cap reached, with whatever it had produced. | | todo.enabled | true | Master switch for todo planning. false means the todo_write tool is never registered — /todo on in such a session saves the setting for next launch and says so, rather than advertising a tool that is not there. | | todo.panel | true | Render the right-hand rail (and, in inline mode, the one-row plan strip). Independent of todo.enabled on purpose: a screen-reader user wants the planning discipline without the column, and the system prompt varies one sentence accordingly. | | todo.followThrough | "notify" | What happens when a run ends with steps left. notify says so and stops; auto continues the plan after a 3-second g