@aragon-agent/cli 0.5.4 → 0.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +747 -577
  2. package/README.md +1163 -995
  3. package/dist/agent/controller.d.ts +71 -1
  4. package/dist/agent/controller.js +135 -1
  5. package/dist/agent/entry-limits.d.ts +65 -0
  6. package/dist/agent/entry-limits.js +133 -0
  7. package/dist/agent/headless.d.ts +29 -0
  8. package/dist/agent/headless.js +86 -1
  9. package/dist/agent/reducer.d.ts +53 -0
  10. package/dist/agent/reducer.js +145 -14
  11. package/dist/agent/system-prompt.d.ts +8 -0
  12. package/dist/agent/system-prompt.js +2 -0
  13. package/dist/cli.js +76 -3
  14. package/dist/commands/builtins.js +171 -0
  15. package/dist/commands/perf.d.ts +45 -0
  16. package/dist/commands/perf.js +78 -0
  17. package/dist/commands/registry.d.ts +27 -1
  18. package/dist/config/env.d.ts +3 -1
  19. package/dist/config/env.js +74 -1
  20. package/dist/config/load.d.ts +41 -0
  21. package/dist/config/load.js +67 -2
  22. package/dist/config/schema.d.ts +108 -8
  23. package/dist/config/schema.js +81 -6
  24. package/dist/config/store.js +10 -1
  25. package/dist/session/persist.d.ts +19 -1
  26. package/dist/session/persist.js +21 -2
  27. package/dist/team/subagent.js +11 -0
  28. package/dist/todo/follow-through.d.ts +117 -0
  29. package/dist/todo/follow-through.js +186 -0
  30. package/dist/todo/limits.d.ts +114 -0
  31. package/dist/todo/limits.js +114 -0
  32. package/dist/todo/normalize.d.ts +33 -0
  33. package/dist/todo/normalize.js +117 -0
  34. package/dist/todo/panel-rows.d.ts +53 -0
  35. package/dist/todo/panel-rows.js +103 -0
  36. package/dist/todo/prompt.d.ts +54 -0
  37. package/dist/todo/prompt.js +76 -0
  38. package/dist/todo/store.d.ts +86 -0
  39. package/dist/todo/store.js +183 -0
  40. package/dist/todo/todo-tool.d.ts +38 -0
  41. package/dist/todo/todo-tool.js +134 -0
  42. package/dist/todo/types.d.ts +62 -0
  43. package/dist/todo/types.js +12 -0
  44. package/dist/tools/index.d.ts +16 -2
  45. package/dist/tools/index.js +13 -0
  46. package/dist/ui/App.js +328 -14
  47. package/dist/ui/Markdown.d.ts +7 -1
  48. package/dist/ui/Markdown.js +15 -48
  49. package/dist/ui/StatusBar.d.ts +31 -0
  50. package/dist/ui/StatusBar.js +7 -2
  51. package/dist/ui/TodoPanel.d.ts +48 -0
  52. package/dist/ui/TodoPanel.js +74 -0
  53. package/dist/ui/TodoStrip.d.ts +36 -0
  54. package/dist/ui/TodoStrip.js +32 -0
  55. package/dist/ui/Transcript.d.ts +56 -4
  56. package/dist/ui/Transcript.js +123 -11
  57. package/dist/ui/entries/AssistantEntry.d.ts +18 -1
  58. package/dist/ui/entries/AssistantEntry.js +33 -3
  59. package/dist/ui/entries/TeamCard.d.ts +9 -1
  60. package/dist/ui/entries/TeamCard.js +22 -1
  61. package/dist/ui/entries/TodoCard.d.ts +39 -0
  62. package/dist/ui/entries/TodoCard.js +57 -0
  63. package/dist/ui/entries/ToolCard.d.ts +13 -1
  64. package/dist/ui/entries/ToolCard.js +39 -5
  65. package/dist/ui/entries/ToolPreview.d.ts +2 -2
  66. package/dist/ui/entries/UserEntry.d.ts +9 -1
  67. package/dist/ui/entries/UserEntry.js +17 -1
  68. package/dist/ui/exit-snapshot.d.ts +7 -0
  69. package/dist/ui/glyphs.d.ts +12 -0
  70. package/dist/ui/glyphs.js +8 -0
  71. package/dist/ui/layout/AppShell.d.ts +34 -1
  72. package/dist/ui/layout/AppShell.js +3 -3
  73. package/dist/ui/layout/MeasuredEntry.d.ts +21 -0
  74. package/dist/ui/layout/MeasuredEntry.js +30 -0
  75. package/dist/ui/layout/ScrollViewport.d.ts +13 -1
  76. package/dist/ui/layout/ScrollViewport.js +10 -4
  77. package/dist/ui/layout/rail.d.ts +56 -0
  78. package/dist/ui/layout/rail.js +68 -0
  79. package/dist/ui/layout/viewport-geometry.d.ts +28 -0
  80. package/dist/ui/layout/viewport-geometry.js +27 -0
  81. package/dist/ui/layout/virtual-window.d.ts +100 -0
  82. package/dist/ui/layout/virtual-window.js +204 -0
  83. package/dist/ui/live-clamp.d.ts +42 -0
  84. package/dist/ui/live-clamp.js +74 -0
  85. package/dist/ui/markdown-blocks.d.ts +25 -1
  86. package/dist/ui/markdown-blocks.js +43 -0
  87. package/dist/ui/overlays/HelpOverlay.js +4 -0
  88. package/dist/ui/render-cache.d.ts +81 -0
  89. package/dist/ui/render-cache.js +195 -0
  90. package/dist/ui/render-governor.d.ts +54 -0
  91. package/dist/ui/render-governor.js +78 -0
  92. package/dist/ui/transcript-text.d.ts +11 -0
  93. package/dist/ui/transcript-text.js +5 -0
  94. package/dist/ui/use-height-store.d.ts +31 -0
  95. package/dist/ui/use-height-store.js +76 -0
  96. package/dist/ui/use-render-governor.d.ts +39 -0
  97. package/dist/ui/use-render-governor.js +57 -0
  98. package/dist/ui/use-startup-notices.d.ts +9 -1
  99. package/dist/ui/use-startup-notices.js +35 -1
  100. package/package.json +3 -2
package/CHANGELOG.md CHANGED
@@ -1,577 +1,747 @@
1
- # Changelog
2
-
3
- All notable changes to `@aragon-agent/cli` are documented here. Entries at
4
- `0.4.x` and earlier refer to the package by its former name, `@argon-agent/cli`
5
- — those releases really were published under that name, so they are left as they
6
- were written.
7
-
8
- ## Unreleased
9
-
10
- ### Added
11
-
12
- - **Output token limits that cannot themselves fail a run.** Every model and
13
- every provider now defaults to 64000 output tokens, and that number is
14
- configurable from the TUI, from a flag, from `ARAGON_MAX_TOKENS`, and by hand
15
- in `~/.aragon-agent/config.json`. Leave it alone and it stays 64000.
16
-
17
- What is new is that the number is an *ambition*. `gpt-4o` caps at 16384 and
18
- `gemini-1.5-pro` at 8192; sending 64000 to either is an HTTP 400 that ends the
19
- turn with a raw provider string in the transcript. The cap is now clamped down
20
- to whatever the target model actually accepts, from a per-model table plus
21
- whatever the provider's own model list reports. For a model nothing knows — a
22
- proxy, a `--base-url` endpoint, something that shipped last week — the request
23
- goes out at 64000, and if the provider objects, `aragon` reads the real ceiling
24
- out of the error text, repairs the request, sends it exactly once more, and
25
- remembers the answer for the rest of the session. One warning line; the run
26
- continues.
27
-
28
- Two combinations that were a guaranteed 400 on every request are fixed with
29
- it: `--thinking xhigh` asks for a 65536-token budget while Anthropic requires
30
- `max_tokens` to be strictly greater than it, and OpenAI's reasoning family
31
- (`o1`, `o3`, `gpt-5`) rejects the `max_tokens` parameter name outright in
32
- favour of `max_completion_tokens`.
33
-
34
- New surfaces: `/max-tokens [<n>|auto|default]`, which with no argument reports
35
- the setting *and* the effective cap for the live model; an `Effective:` line
36
- under the settings screen's `Max tokens` field, so a value the model will not
37
- honour is visible before you save it; `--max-tokens auto`; and
38
- `aragon config set maxTokens <n|auto|default>`, which echoes the value that was
39
- actually stored rather than the one you typed.
40
-
41
- - **Team subagents.** The agent can now hand independent parts of a job to up to
42
- five short-lived subagents that run in parallel, then read one combined report
43
- of what each of them found. It decides for itself whether to delegate, so a
44
- session that never calls the new `task` tool is byte-for-byte the session that
45
- existed before. On by default; `--no-team` or `team.enabled: false` turns it
46
- off, and `aragon config set team.maxSubagents <n>` sets the width (1-10; the
47
- 10 is a hard ceiling no config file can raise).
48
-
49
- A subagent is a full agent with the same tools and working directory but no
50
- memory of your conversation, so its brief has to be self-contained. It cannot
51
- delegate further and it cannot ask you anything. Plan mode and a skill's
52
- `allowed-tools` ceiling both reach one level down, so delegating is never a
53
- way around either; `--confirm` queues subagent confirmations one at a time and
54
- labels each with the subagent that is asking.
55
-
56
- Subagents can message each other with `team_send` / `team_wait`, delivered by
57
- attaching the message to the recipient's next tool result rather than
58
- interrupting it. The limits are deliberate — 6 messages each, one every 15
59
- seconds, 24 per dispatch — and every refusal is a plain result naming the
60
- limit rather than an error, because an error invites the retry the limits
61
- exist to prevent.
62
-
63
- While a dispatch runs, a roster sits between the transcript and the composer
64
- and the status bar carries `agents 3/5`; both disappear when it finishes and
65
- the transcript keeps a card you can expand with `Ctrl+O`. `Esc` aborts every
66
- subagent and returns the partial report. Under `-p` the transitions go to
67
- stderr and the subagents' tokens are folded into the `[usage]` footer, so the
68
- cost readout cannot under-report what the team spent.
69
-
70
- Full documentation, including the limits table and how team mode interacts
71
- with plan mode, skills and `--confirm`, is in the README.
72
-
73
- - **The subagent roster now shows what each subagent is doing, and shows the
74
- ones that are working.** Where every row used to say `thinking` for minutes at
75
- a time, it now says `bash: npm test -w cli`, `read: src/api/routes.ts`,
76
- `waiting for a2`, or the tail of the sentence the subagent is currently
77
- writing. On a narrow terminal the same row falls back to a file name and a
78
- program name rather than wrapping, and the elapsed clock keeps its place at
79
- every width.
80
-
81
- The five visible rows are now the five that matter: whatever is running comes
82
- first, then whatever is queued, then the most recent results. Above five
83
- subagents the old panel showed the five that had finished first and hid
84
- everything still working behind `+3 more`, which is the opposite of what the
85
- roster is for. `+3 more` now says how many of the hidden ones are still going.
86
-
87
- - **A subagent no longer waits two minutes for a message nobody can send.**
88
- `team_wait` now checks whether anyone could actually answer before it blocks:
89
- if the teammate it named has already finished, does not exist, or is itself
90
- waiting in a way that cannot be released in time, it returns straight away and
91
- says which. Nothing is refused that could still have been answered — including
92
- by a third teammate further down the chain — and the subagent is told what to
93
- do instead rather than handed an error.
94
-
95
- - **A subagent whose very first request dies on a rate limit is retried once.**
96
- Only a genuine cold start qualifies: no turn completed and no tool ran, so
97
- there is nothing to undo. It restarts after two seconds, the roster says
98
- `starting (retry)`, and the report notes `retried 1x`. Pressing `Esc`, a
99
- timeout, or any subagent that had already begun work is never retried.
100
-
101
- ### Changed
102
-
103
- - **`"maxTokens": null` in `config.json` now means AUTO** — use each model's own
104
- ceiling, never above 64000. It previously resolved to 64000 by accident (the
105
- layered resolver skipped `null`), and there was no way to express AUTO through
106
- any supported write path. If you have a `null` there today, the only difference
107
- is a downward clamp on models whose real ceiling is below 64000 — the direction
108
- that prevents failures rather than causing them. Absent still means 64000, and
109
- an explicit number still means that number.
110
-
111
- - **`config.json` holds settings again.** The prompts you type are no longer
112
- stored in it. They move to `~/.aragon-agent/prompt-history.jsonl` — one JSON
113
- object per line, `0600` on POSIX — and the submit counter and the "notice
114
- already shown" flag move to `~/.aragon-agent/state.json`. `↑` and `↓` behave
115
- exactly as before.
116
-
117
- Two things get better. Opening `config.json` to change your model no longer
118
- means scrolling past a transcript of your own typing, and copying it to
119
- another machine no longer carries your prompts along. And submitting a message
120
- no longer rewrites the file that holds your API keys: `config.json` is written
121
- when you change a setting, and at no other time.
122
-
123
- **Your history and counters are migrated automatically, once, at the next
124
- launch.** Nothing is printed, because nothing changes for you. The dead
125
- `recentModels` key — which nothing has ever written — is dropped.
126
-
127
- If you go back to 0.5.x after upgrading, that version does not know about the
128
- new file and `↑` will look empty. Nothing has been lost: the entries are still
129
- in `prompt-history.jsonl`, and upgrading again brings them back.
130
-
131
- ### Added
132
-
133
- - **`aragon history`** — `path`, `list` (`-n`, `--json`) and `clear --yes` for
134
- the prompt history, alongside the existing `aragon logs` commands. Entries are
135
- stored verbatim, so `clear` is how you erase them; `aragon config set
136
- historyEnabled false` stops new ones being recorded without deleting or hiding
137
- what is already there.
138
-
139
- - **The mouse wheel scrolls what is under the pointer.** In full-screen mode the
140
- wheel now scrolls the transcript three rows per notch (a page with `Shift`),
141
- scrolls an open overlay when the pointer is over one, and steps prompt history
142
- one entry per notch when the pointer is over the input box — the same code
143
- path `↑` / `↓` use, so it inherits the rule that an in-progress draft is never
144
- overwritten. A slim rail on the viewport's right edge shows where you are in
145
- the conversation.
146
-
147
- **This fixes a destructive bug.** Previously the wheel recalled prompt history
148
- no matter where the pointer was, because the alternate screen makes terminals
149
- translate each notch into arrow keys. Wheeling while composing a message
150
- silently replaced the draft with an old prompt, and nothing scrolled.
151
-
152
- **Selecting text with the mouse now requires `Shift`+drag** in most terminals.
153
- That is the standard convention for "an application is tracking the mouse" and
154
- it applies to everyone, including people who never scroll with the wheel — so
155
- the first session says so once, in the transcript, and never again. Turn the
156
- whole feature off with `--no-mouse`, `ARAGON_MOUSE=0`, or
157
- `aragon config set mouse false`; the wheel then does nothing rather than
158
- reverting to the old behaviour. Inline mode (`--no-fullscreen`) is untouched:
159
- your terminal's own scrollback already does the right thing there.
160
-
161
- Under `tmux` with `mouse on`, tmux keeps the wheel for itself and the app
162
- never sees it. `set -g mouse off` hands it back.
163
-
164
- ### Changed
165
-
166
- - **Your files moved to `~/.aragon-agent/`.** Config, sessions, installed skills
167
- and the usage counters now live in one directory in your home — on Windows
168
- `C:\Users\<you>\.aragon-agent\`, and the same path on macOS and Linux. They
169
- used to be split across `%APPDATA%\aragon-agent-nodejs\Config` and
170
- `%LOCALAPPDATA%\aragon-agent-nodejs\Data` (or the XDG equivalents), which are
171
- correct locations and terrible answers to "where do I change the model?".
172
-
173
- **The move happens once, automatically, on first launch, and prints a line on
174
- stderr when it does.** Nothing is deleted: `config.json` is COPIED rather than
175
- moved, and the old directories are left where they are, so reinstalling 0.5.0
176
- remains lossless. `aragon config home` prints the new location and names the
177
- old ones. Once you are satisfied, you can delete them yourself.
178
-
179
- `ARAGON_HOME` relocates the whole tree. It has to be a real environment
180
- variable — the path is resolved before any `.env` is read, so putting it in a
181
- `.env` will not work. `aragon config home` always prints what is actually in
182
- use.
183
-
184
- ### Added
185
-
186
- - **Logging.** Records go to `~/.aragon-agent/logs/aragon-<date>.log` as JSON
187
- Lines: startup and exit, config writes, turn boundaries with token counts,
188
- tool names with durations, skill loads, and every uncaught error. Files rotate
189
- by day and by size (`log.maxFileBytes`, default 5 MiB) and the oldest beyond
190
- `log.maxFiles` (default 10) are deleted.
191
-
192
- **`info`, the default, records no conversation content**, so attaching a log
193
- to a bug report is safe. `--log-level debug` (or `--verbose`) adds prompts,
194
- replies and tool arguments truncated to `log.previewChars`; `trace` adds them
195
- in full. Those two write what you typed — check before sharing one.
196
-
197
- API keys are removed at every level by two independent passes: fields whose
198
- name looks like a credential are blanked whatever they hold, and every string
199
- is scanned both for known key formats and for the literal keys this process is
200
- holding — which is what covers a custom endpoint whose key looks like nothing
201
- in particular. `log.redactSecrets false` turns both off and warns you on
202
- stdout when you set it.
203
-
204
- Nothing is ever uploaded. There is no network path out of this subsystem.
205
-
206
- New commands: `aragon logs path | list | tail [-n N] [--follow] [--level lv]
207
- [--json] | clear --yes | open`, and `/logs` inside the TUI. New flags:
208
- `--log-level`, `--verbose`, `--log-file` / `--no-log-file`, `--log-dir`. New
209
- environment variables: `ARAGON_LOG_LEVEL`, `ARAGON_LOG_FILE`, `ARAGON_LOG_DIR`
210
- — these three, unlike `ARAGON_HOME`, can come from a `.env`.
211
-
212
- - **`aragon config get <key>` / `list [--json]` / `edit` / `home`.** `get` and
213
- `list` mask every secret, `--json` included. `edit` opens `config.json` in
214
- `$VISUAL` / `$EDITOR` (`notepad` on Windows), takes a `config.json.bak` first,
215
- and re-parses on exit — an invalid edit is reported immediately, and the
216
- backup is named in the message.
217
-
218
- - **`/reload`** re-reads `config.json` into the running session, for when you
219
- have edited it in another window. Refused while a run is in progress: swapping
220
- the model mid-turn would let the second half of an answer come from different
221
- settings than the first, with nothing afterwards able to explain the result.
222
-
223
- - **Log level in the settings screen**, alongside provider / model / thinking.
224
- The rest of the log settings — and `redactSecrets` above all — stay
225
- command-line-only, so the one switch that can put credentials on disk cannot
226
- be flipped with an arrow key.
227
-
228
- ### Fixed
229
-
230
- - **A malformed `config.json` no longer resets everything in silence.** A stray
231
- comma used to send the model, theme, timeouts, skills and (as far as you could
232
- tell) your API key back to defaults, with nothing anywhere explaining it. The
233
- fallback is unchanged — a bad config still never stops the CLI from starting —
234
- but it now says so, and records why.
235
-
236
- - **Ctrl+C now flushes pending log records in every mode.** The signal handlers
237
- only existed in the full-screen branch, so `-p`, the inline renderer and every
238
- subcommand took Node's default termination, which does not run exit handlers.
239
-
240
- ### Added
241
-
242
- - **Plan mode.** `Shift+Tab` toggles between `BUILD` (everything as before) and
243
- `PLAN`, a read-only research-and-design posture. `/plan [on|off|status]` is a
244
- first-class equivalent for terminals that swallow `CSI Z`, and `--plan` /
245
- `--no-plan` / `ARAGON_PLAN=1` / `planModeDefault` cover the startup case.
246
-
247
- In `PLAN`, `write_file`, `edit_file`, `bash`, `skill_install` and
248
- `skill_create` are refused **at the tool boundary**, so read-only is a
249
- property of the wiring rather than a promise in a prompt. `bash` is refused in
250
- full, `git status` included: a shell string cannot be classified reliably, and
251
- a gate that is right most of the time is worse than one that is always right,
252
- because you stop trusting the badge. The refusal names `read_file` / `glob` /
253
- `grep` as the alternatives.
254
-
255
- Two tools exist only while a human is attached. `ask_user` renders a
256
- keyboard-driven wizard - 1-5 questions, 2-4 options each, exactly one marked
257
- `RECOMMENDED`, plus an `Other...` free-text option - where pressing `Enter`
258
- through the wizard accepts every recommendation. `submit_plan` renders the
259
- plan as a scrollable card: `a` approves, `r` sends written feedback (`<-`
260
- returns to the card), `Esc` dismisses. **Approving flips the session to
261
- `BUILD` immediately and the same run continues into implementation.**
262
-
263
- Dismissing a plan asks for a better one rather than stopping - the agent is
264
- told to refine and resubmit - so the way out of a run is `Esc` twice: the
265
- first closes the card, the second aborts the run.
266
-
267
- Toggling mid-run is asymmetric on purpose: `build -> plan` applies at once,
268
- `plan -> build` is deferred to the end of the run (the status bar shows
269
- `PLAN -> BUILD` meanwhile) so a run launched under a read-only guarantee
270
- cannot start writing files because of one stray keypress.
271
-
272
- `aragon -p --plan "..."` registers no question or plan tool - there is nobody
273
- to ask - but the read-only gate still applies, so it means "tell me how you
274
- would do this, and do not touch my repository".
275
-
276
- - Three flat config keys: `planModeDefault` (default `false`),
277
- `planModeMaxAskRounds` (default `4`, clamped `[1, 10]`) and
278
- `planModeHumanTimeoutMs` (default `1800000`, clamped `[60000, 7200000]`). All
279
- three are settable with `aragon config set`. Additive, as always: a config
280
- file written by an earlier version loads unchanged.
281
-
282
- ### Fixed
283
-
284
- - A `--confirm` prompt no longer races the idle watchdog. Taking longer than
285
- `idleTimeoutMs` over `Proceed? (y/N)` used to abort the run with no
286
- explanation; every human wait now suspends the watchdog and restarts it in a
287
- `finally`.
288
-
289
- - Honor an explicit `NODE_TLS_REJECT_UNAUTHORIZED=0` setting in the CLI and the
290
- official npm release workflow while hiding only Node's standard insecure-TLS
291
- warning. Other process warnings remain visible.
292
-
293
- ## 0.5.0
294
-
295
- ### Breaking
296
-
297
- - **The package is renamed `@argon-agent/cli` → `@aragon-agent/cli`.** The brand
298
- was always meant to be *Aragon*, matching AragonMesh; the missing `a` was a
299
- typo that reached the registry. Install with:
300
-
301
- ```
302
- npm uninstall -g @argon-agent/cli
303
- npm install -g @aragon-agent/cli
304
- ```
305
-
306
- `@argon-agent/cli` is deprecated and receives no further releases. **The
307
- executable is still `aragon`** — the command you type does not change.
308
-
309
- - **Environment variables are `ARAGON_*`, not `ARGON_*`.** There is no
310
- compatibility fallback: `ARGON_MODEL`, `ARGON_PROVIDER`, `ARGON_BASE_URL`,
311
- `ARGON_THINKING`, `ARGON_MAX_TOKENS`, `ARGON_THEME`, `ARGON_FULLSCREEN`,
312
- `ARGON_SKILLS`, `ARGON_SKILLS_DISABLED`, `ARGON_SKILLS_PATH` and
313
- `ARGON_REDUCED_MOTION` are all ignored from this release on. Rename them in
314
- your shell profile and CI. Provider keys (`ANTHROPIC_API_KEY`,
315
- `OPENAI_API_KEY`, `GOOGLE_API_KEY`, `GEMINI_API_KEY`) are untouched.
316
-
317
- - **The project-level skills directory is `.aragon/skills`, not
318
- `.argon/skills`.** This one lives in your repository, so rename it yourself:
319
-
320
- ```
321
- git mv .argon .aragon
322
- ```
323
-
324
- A config file that already persisted the old default keeps working — an
325
- explicitly saved `skills.projectDirs` still wins over the default — but the
326
- shipped default is now `['.aragon/skills', '.claude/skills']`. Update it with
327
- `aragon config set` if you want the new default.
328
-
329
- ### Added
330
-
331
- - **Automatic migration of your user-level state.** On first run, 0.5.0 moves
332
- the `env-paths` config and data directories from `argon-agent` to
333
- `aragon-agent` — your API key, sessions and installed skills come with it, and
334
- each installed skill's `.argon-skill.json` manifest is renamed to
335
- `.aragon-skill.json` so `skills update` and `skills uninstall` still recognise
336
- it. The migration prints one line to **stderr**, runs once, and is skipped
337
- entirely if the new directory already exists. If it fails for any reason the
338
- CLI still starts; the old directory is never deleted when a cross-volume copy
339
- was needed.
340
-
341
- - The opening wordmark now reads `ARAGON` and is 52 columns wide (was 44).
342
- Terminals between 52 and 55 columns show the single-line banner rather than a
343
- clipped wordmark.
344
-
345
- - **Skills.** A skill is a directory holding a `SKILL.md` (YAML frontmatter +
346
- Markdown body) plus optional `reference/`, `scripts/` and `assets/`. Skills
347
- reach the model through three levels of progressive disclosure: a name +
348
- one-line "when to use" catalog in the system prompt (≤ 6 000 bytes total),
349
- the full body only when the model calls the `skill` tool, and bundled files
350
- only when it reads them with `read_file` / `bash`. A skill therefore costs a
351
- line of context rather than its whole body. How many fit in Level 1 depends on
352
- description length and language — roughly 30 with terse English descriptions,
353
- roughly 10 with Chinese ones at the character cap; past that the catalog
354
- truncates and `skill_find` covers the remainder.
355
- - Four model-facing tools: `skill` (load), `skill_find` (search installed
356
- skills), `skill_install` (install from a local directory, git repo, or https
357
- `SKILL.md` / `.zip`) and `skill_create` (author a new one from a procedure the
358
- agent just worked out).
359
- - **`aragon skills update <name> | --all`**, with `--dry-run`, `--force` and
360
- `--check`. Re-fetches from the source recorded in the install manifest,
361
- preserving `installedAt` and recording `updatedAt` / `previousVersion`. Refuses
362
- before downloading anything when the installed copy has local edits, and
363
- re-validates the source against the *current* `skills.allowedHosts` rather than
364
- the one in force at install time. Not exposed to the model.
365
- - **Catalog ranking.** Level 1 entries are ordered by scope, then by how recently
366
- and often each skill was used, so truncation drops what you do not use rather
367
- than what sorts last alphabetically. With no usage data the order is unchanged.
368
- - **`skill_find`**, advertised in the prompt only when the catalog actually
369
- truncated. Searches installed skills by name, description and keyword; never
370
- reaches the network, never returns `activation: manual` skills, and tells the
371
- model to ask for a source rather than invent one when nothing matches.
372
- - **Cross-process install lock.** Install / create / remove / update take a
373
- per-directory advisory lock, closing a race in which two concurrent installs
374
- could interleave their atomic-replace steps and delete a skill with no error.
375
- Self-expires after 60 s; waits at most 5 s; only ever released by its owner.
376
- - **Load-time integrity.** Discovery re-checks `SKILL.md` against the sha256
377
- recorded at install, at no extra I/O. `skills.integrity` selects
378
- `off` / `warn` (default) / `strict`.
379
- - **Local usage counters** at `<data>/skill-usage.json` — skill name, count and
380
- timestamp only, never transmitted, disabled with `skills.usageTracking=false`.
381
- Automatically injected `activation: always` skills are not counted.
382
- - Config keys `skills.integrity` and `skills.usageTracking`; `aragon skills list
383
- --sort=recent` and `/skills list --sort=recent`.
384
- - Every usable skill also becomes a slash command: `/<skill-name> [args]`, with
385
- `$ARGUMENTS` / `$1..$9` substitution. On a name clash the built-in command
386
- always wins and the skill is reachable as `/skill:<name>`.
387
- - `/skills` management: `list`, `info`, `install`, `remove`, `enable`,
388
- `disable`, `reload`, `create`, `trust`, `untrust`.
389
- - `aragon skills …` non-interactive equivalents plus `path` and `doctor`.
390
- Exit codes follow `config set`: `0` ok, `1` run-time failure, `2` usage.
391
- - Four discovery scopes in ascending precedence: bundled (`<pkg>/skills`), user
392
- (`<data>/skills`), project (`<cwd>/.aragon/skills` and, read-only,
393
- `<cwd>/.claude/skills` for Claude Code interop), and `ARAGON_SKILLS_PATH`.
394
- - New flags `--no-skills`, `--skill <name>` (repeatable) and `--skills-yes`;
395
- env `ARAGON_SKILLS`, `ARAGON_SKILLS_PATH`, `ARAGON_SKILLS_DISABLED`; config keys
396
- `skills.enabled`, `skills.requireApproval`, `skills.catalogMaxBytes`,
397
- `skills.bodyMaxBytes`.
398
- - One bundled skill, `skill-creator`, documenting how to write a good one.
399
- - New runtime dependency: `fflate` (~30 KB, MIT, zero transitive deps) for zip
400
- extraction. `@aragon-agent/core` gains no dependency.
401
- - **Release tooling for the scope change.** `npm run verify:brand` scans every
402
- file that `npm pack` would put in the tarball — README and `dist/` included —
403
- and blocks the release on any surviving `argon` reference, with only the four
404
- documented exceptions (the two CHANGELOGs and the legacy-state migration
405
- module, which hold the old names by definition). `packages/cli` also gains a
406
- `prepublishOnly: npm run build`, so a publish that bypasses
407
- `publish-latest.ps1` can no longer ship a `dist/` that is out of step with the
408
- sources. `deprecate-legacy.ps1` retires `@argon-agent/*` on the registry, and
409
- refuses to do so until the replacements are actually published.
410
-
411
- ### Changed
412
-
413
- - The globally installed executable is now `aragon`. The previous `argon` and
414
- `argon-agent` aliases are no longer installed.
415
- - `config/store.ts` now deep-merges the `skills` section on both read and write,
416
- the same treatment `apiKeys` already received. Without it a partial patch such
417
- as the one `/skills disable` sends would replace the whole section and
418
- silently discard `trustedProjectDirs`, `allowedHosts` and `requireApproval`.
419
- - `slashSuggestions` accepts `-` and `:`, so kebab-case and `skill:`-namespaced
420
- commands autocomplete. Previously `/my-sk` produced no popup at all.
421
- - `AgentController` now has a single `agent.setSystemPrompt()` call site, so a
422
- `/cwd` change can no longer drop the skill catalog out of the prompt.
423
- - With skills off or none installed, the system prompt and the 7-tool array are
424
- byte-identical to the previous release.
425
- - Added a repository-level PowerShell release workflow that automatically
426
- updates CLI and Core versions, synchronizes their dependency and lockfile,
427
- verifies both tarballs, and publishes them in dependency order.
428
-
429
- ### Security
430
-
431
- - Installing a skill requires an explicit human approval that **probes for a
432
- human first and refuses when there is none**. Under `-p` there is no TUI and
433
- therefore no approver, so `skill_install` is refused with an actionable
434
- message rather than writing a third-party directory unattended. Use
435
- `--skills-yes` (or `skills.requireApproval=false`) to opt out deliberately.
436
- - Project skill directories require a one-time trust confirmation before they
437
- are loaded — cloning an unfamiliar repository does not grant it the ability
438
- to inject instructions into your session.
439
- - Git is invoked only via `execFile` with an argv array and `shell: false`, and
440
- owner / repo / ref / subdirectory fragments are whitelisted and refused if
441
- they begin with `-`. A leading dash matters even with a pure argv array:
442
- `--upload-pack=<program>` makes git execute that program.
443
- - Zip extraction is streamed and gated on **actually written** bytes, per-entry
444
- size, compression ratio and entry count, all of which can abort mid-archive.
445
- The size a zip *declares* is written by whoever built it and is never trusted.
446
- Path traversal, absolute entries, symlinks and Windows device names are
447
- refused, and a rejected archive is removed rather than left half-extracted.
448
- - Network fetches are `https:` only, restricted to `skills.allowedHosts`,
449
- re-checked on every redirect (max 3), size-capped, and refuse IP literals and
450
- loopback.
451
- - Nothing a skill ships is executed at install time, and the executable bit is
452
- not preserved. Scripts run only when the model invokes `bash` explicitly.
453
- There is no sandbox: approval blocks *silent* installation, it does not make
454
- a skill you approved safe.
455
-
456
- ## 0.3.0
457
-
458
- A full-screen TUI release. `@argon-agent/core` is untouched, no new runtime
459
- dependency is added, and the headless/print contract, exit codes, and
460
- slash-command semantics are unchanged. The 0.2.0 inline renderer remains
461
- available in full via `--no-fullscreen`.
462
-
463
- ### Added
464
-
465
- - **Full-screen mode (default).** `aragon` now takes over the terminal's
466
- alternate screen buffer — the same mechanism `vim` / `htop` / `lazygit` use.
467
- Your shell history is covered, not erased, and comes back untouched on exit.
468
- The frame is a fixed `rows - 1` tall, so **the composer and the status bar sit
469
- at the physical bottom of the screen from the very first frame**: empty
470
- session, long session, mid-scroll, or overlay open.
471
- - **Brand region.** A six-row gradient ASCII wordmark on a roomy empty session,
472
- degrading to a banner, then a single-line bar, then a bare wordmark as space
473
- runs out. Row 1 always begins with the brand glyph.
474
- - **Self-drawn scrolling.** `PgUp` / `PgDn` by the page, `Shift+↑` / `Shift+↓` by
475
- the line. The viewport auto-follows new output while pinned to the bottom;
476
- scrolling away shows `↑N` in the status bar plus a "N new lines" hint, and
477
- submitting a message always re-pins.
478
- - **Exit replay.** After leaving the alternate screen the session is replayed
479
- into the normal buffer as plain, colorless text, so the conversation does not
480
- evaporate with the screen. Turn it off with `--no-exit-transcript`.
481
- - **New flags** `--fullscreen` / `--no-fullscreen` / `--no-exit-transcript`, the
482
- env var `ARGON_FULLSCREEN=0|1`, and the config keys `fullscreen`,
483
- `exitTranscript`, and `transcriptWindow`.
484
- - **Automatic downgrade.** A non-TTY stdout, `TERM=dumb`, CI, and terminals under
485
- 12 rows / 40 columns fall back to the inline renderer. Only the non-TTY gate is
486
- un-overridable — `--fullscreen` beats the rest.
487
-
488
- ### Changed
489
-
490
- - The status bar lost its round border and is now exactly one row; it had been
491
- spending an eighth of a 24-row terminal framing a single line of text.
492
- - The toast strip holds a fixed row in full-screen mode, so the transcript no
493
- longer jumps as toasts appear and expire.
494
- - The composer is a rounded frame whose border color reports state (idle, has a
495
- draft, running, blurred by an overlay), with the completion popup above it.
496
- - `Ctrl+L` repaints the frame instead of writing a clear sequence. Ink dedupes
497
- identical output at two separate gates, so under a fixed frame the old
498
- approach erased the screen and then declined to redraw it.
499
- - `Shift+↑` / `Shift+↓` no longer recall prompt history — they scroll.
500
- - Full-screen mode routes `console.*` into the transcript as notices rather than
501
- letting Ink write them straight to stdout, which corrupts the frame's line
502
- accounting.
503
-
504
- ### Known trade-offs
505
-
506
- - The terminal's native scrollback and mouse wheel do not scroll the transcript
507
- in full-screen mode; use `PgUp` / `PgDn`, or run with `--no-fullscreen`.
508
- - Mouse tracking is deliberately left off: enabling it costs text selection and
509
- copy in most terminals.
510
- - Should a crash ever strand your terminal on the alternate screen, `reset`
511
- restores it. Four independent restore paths exist to prevent that: normal
512
- exit, `process.exit`, `SIGINT` / `SIGTERM` / `SIGHUP`, and Ink's own signal
513
- handling.
514
-
515
- ## 0.2.0
516
-
517
- A design-elevation & HCI-hardening release. No breaking changes: `@argon-agent/core`
518
- is untouched, no new runtime dependency is added, and the headless/print contract,
519
- exit codes, config keys, and slash-command semantics from 0.1.0 are unchanged.
520
-
521
- ### Added
522
-
523
- - **Real theming engine.** Distinct `dark` / `light` palettes with an `auto`
524
- resolution (`auto → dark`), color degradation across terminal depth
525
- (truecolor → 256 → 16 → monochrome), and an ASCII glyph fallback for terminals
526
- without Unicode. Honors `NO_COLOR`, `FORCE_COLOR`, `--no-color`, and
527
- `TERM=dumb`. Switch live with `/theme <auto|dark|light>` (persisted).
528
- - **Elegant chrome.** A gradient wordmark header that collapses to a slim sticky
529
- bar after the first turn, a first-run **Welcome / empty-state** card, and a
530
- status bar with a colored **context gauge** (threshold colors), a **tokens/sec**
531
- read-out while running, and a contextual hint.
532
- - **Legible tool output.** Colored unified diffs (green adds / red removes) and
533
- per-tool rich previews (`edit_file`/`write_file`/`read_file`/`bash`/`list_dir`/
534
- `glob`). Long previews collapse to 8 lines and expand with `Ctrl+O` or
535
- `/expand [n]`.
536
- - **Autocomplete.** A slash-command palette and `@file` path completion popup
537
- (`Tab`/`→` to complete, `Up`/`Down` to move, `Esc` to close).
538
- - **Full line editing.** Home/End, word jump/delete, kill-to-start/end, and
539
- multi-line vertical cursor navigation, with prompt-history recall at the edges.
540
- Unknown control/escape sequences are dropped instead of inserted.
541
- - **Reliability under load.** Ink `<Static>` finalization for settled entries and
542
- a streaming delta coalescer, so long/fast sessions stay flicker-free.
543
- - **Calm feedback.** Ephemeral, auto-dismissing **toasts** for transient acks;
544
- the transcript keeps only durable content (messages, tool cards, run errors).
545
- - `reducedMotion` config (also `ARGON_REDUCED_MOTION`; implied by `--no-color`)
546
- replaces spinners with a static glyph.
547
-
548
- ### Changed
549
-
550
- - History scrollback now uses the **native terminal scrollback** that `<Static>`
551
- prints into (this supersedes the never-implemented `PgUp`/`PgDn` promise).
552
-
553
- ## 0.1.0
554
-
555
- Initial release — a Claude-Code / Codex-style interactive terminal UI (TUI) on
556
- top of `@argon-agent/core`.
557
-
558
- ### Added
559
-
560
- - **Interactive TUI** (React + Ink): gradient header, streaming transcript with
561
- markdown + syntax highlighting, collapsible thinking blocks, live tool-call
562
- cards, a status bar (model / context % / tokens / cost / elapsed), and modal
563
- overlays (settings, model picker, help, confirm).
564
- - **Built-in toolset** wired into the core agent at full permission:
565
- `read_file`, `write_file`, `edit_file`, `list_dir`, `glob`, `grep`, `bash`.
566
- - **Layered configuration** (defaults → user file → env/`.env` → flags) with
567
- live in-TUI editing of provider / model / base URL / API keys / thinking level
568
- / max tokens. Secrets are masked and the config file is written `0600` on POSIX.
569
- - **One-shot / print mode** (`argon -p`) for scripting and piping, plus
570
- `argon config` / `argon config set` / `argon config path` / `argon models`.
571
- - **Session control**: abort (Esc), steer-while-running, follow-up queue,
572
- double-Ctrl-C exit, `/save` / `/resume` JSON sessions.
573
- - **Timeout invariant** (`idleTimeout ≥ toolTimeout`) so a long single tool run
574
- is never killed by the idle watchdog.
575
- - **Never-silent failures**: pre-flight API-key validation, error-StreamEvent
576
- rendering, and a guard that surfaces a swallowed agent error instead of a
577
- blank no-op (headless exits `1`/`2` accordingly).
1
+ # Changelog
2
+
3
+ All notable changes to `@aragon-agent/cli` are documented here. Entries at
4
+ `0.4.x` and earlier refer to the package by its former name, `@argon-agent/cli`
5
+ — those releases really were published under that name, so they are left as they
6
+ were written.
7
+
8
+ ## Unreleased
9
+
10
+ ### Changed
11
+
12
+ - **A long session stays as fast as a short one.** The TUI used to get slower as
13
+ a session grew and, past a threshold, stopped making progress at all. That was
14
+ structural rather than incidental: Ink has no output caching, so every frame
15
+ re-walked the entire mounted tree, re-measured every text node and
16
+ re-serialised the frame. The per-frame cost was therefore proportional to every
17
+ character the session had ever produced — and `transcriptWindow` bounded the
18
+ entry *count*, which bounds nothing when one entry can be fifty thousand lines.
19
+
20
+ Entries outside the visible band are no longer mounted. The viewport renders
21
+ what you can see plus a couple either side and replaces the rest with two
22
+ spacers of the right height, so the frame costs what the screen costs.
23
+ Scrolling, the `↑N` readout and the wheel routing are untouched. Because the
24
+ horizon is no longer a rendering budget, `transcriptWindow` rises from 300 to
25
+ 1000 and its ceiling from 2000 to 20000; an existing setting is still valid
26
+ and still clamps.
27
+
28
+ Syntax highlighting and markdown parsing are memoised on their input, so a
29
+ 200-line code block is tokenised once rather than thirty times a second for as
30
+ long as it stays on screen. Only the *parsed* form is cached and never a themed
31
+ one, so `/theme` still takes effect on the next frame.
32
+
33
+ Under genuine load the streaming interval widens — 33 ms up to a 320 ms
34
+ ceiling — so keystrokes and `Ctrl+C` do not queue behind renders. This is
35
+ visible rather than silent: a muted **`eco`** chip appears in the status bar
36
+ while it is in effect, because a user who cannot see why the stream got
37
+ chunkier will conclude the model got slower. `--no-render-governor`,
38
+ `renderGovernor: false` or `ARAGON_RENDER_GOVERNOR=0` turns it off;
39
+ `--max-render-interval 33` flattens the ladder without disabling the mechanism.
40
+
41
+ - **A live thinking block no longer grows without limit.** While an answer is
42
+ streaming, visible thinking is clamped to its newest 24 rows behind a
43
+ `... N earlier lines` marker, and the whole block renders again the moment the
44
+ answer settles. Thinking is scratch reasoning you read from its newest end, and
45
+ an unbounded one was the easiest way for a single live entry to fill the
46
+ viewport on its own.
47
+
48
+ ### Fixed
49
+
50
+ - **Inline mode could hard-freeze the terminal, and now cannot.** Once a live
51
+ entry grew taller than the terminal, Ink took a branch that writes
52
+ `clearTerminal` plus the *entire accumulated session history* on every
53
+ subsequent frame — bypassing both of its own dedupe gates, and growing without
54
+ bound for the rest of the session. Any inline user (`--no-fullscreen`,
55
+ `TERM=dumb`, CI, a terminal under 12 rows or 40 columns) whose model wrote a
56
+ long answer could reach it. The live region is now clamped below that
57
+ threshold, with a `... N earlier lines` marker naming what is deferred. Nothing
58
+ is lost: the entry prints in full into the terminal's own scrollback the moment
59
+ it settles.
60
+
61
+ - **The view state no longer grows without a ceiling.** A single assistant answer
62
+ is capped at 256 KiB in the view (thinking at 64 KiB, streamed tool arguments
63
+ at 16 KiB) by eliding the MIDDLE, so both the opening and the live cursor
64
+ survive; a marker states how many characters went. `transcriptRetain`
65
+ (default 1000) caps the entries kept in memory, and what it removed is counted
66
+ and reported both by `/perf` and at the top of the exit replay. A model that
67
+ emits five megabytes no longer makes every later frame a five-megabyte scan.
68
+
69
+ ### Added
70
+
71
+ - **`/perf`.** Reports what the renderer is actually doing: the frame interval
72
+ and the last commit cost, how many entries exist / are retained / were dropped
73
+ / are mounted, height-cache and render-cache occupancy, and the viewport
74
+ geometry. `/perf reset` clears the caches and returns the governor to its
75
+ fastest rung. Silent degradation is the one thing a claim of robustness cannot
76
+ afford, and this is the place that names it.
77
+
78
+ - **Three configuration keys**, each with a flag and an environment override:
79
+ `transcriptRetain` (`--transcript-retain`, `ARAGON_TRANSCRIPT_RETAIN`),
80
+ `renderGovernor` (`--render-governor` / `--no-render-governor`,
81
+ `ARAGON_RENDER_GOVERNOR`) and `maxRenderIntervalMs`
82
+ (`--max-render-interval`, `ARAGON_MAX_RENDER_INTERVAL_MS`). No migration and no
83
+ config version bump: a file written before they existed loads unchanged.
84
+ `transcriptRetain` is raised to `transcriptWindow` when the two conflict —
85
+ retaining less than you can scroll to would make part of the horizon
86
+ unreachable — and a startup notice names both numbers, because overriding a
87
+ value you typed and saying nothing is the one thing none of this may do.
88
+
89
+ - **Following the plan through, on a budget you can do arithmetic on.** A run
90
+ that ended with steps outstanding used to print one sentence and stop. It now
91
+ asks three questions the CLI already knew the answers to — did you abort it,
92
+ did it error, did the list move — and does one of three things.
93
+
94
+ With the default `notify` the sentence is unchanged, except that a run **you**
95
+ cancelled with `Esc` now says nothing at all: being told what you just
96
+ interrupted is the CLI answering a question nobody asked.
97
+
98
+ With `/todo follow auto` it continues the plan itself, after announcing
99
+ `Continuing with 4 remaining steps in 3s - Esc to stop.` Auto-continuation was
100
+ refused last release as "an unbounded cost loop wearing a helpful hat", and
101
+ that judgement stands — what changed is that the loop is now bounded first.
102
+ A continuation that completes no step buys exactly one more attempt; a single
103
+ plan is continued at most 25 times however productive it looks; and a re-plan
104
+ forgives the first counter but never the second, so a model that reshapes its
105
+ list every turn cannot lift the ceiling. A run that ended with an error never
106
+ auto-continues in any mode. `Esc` cancels, and so does typing anything.
107
+
108
+ Whatever sends the continuation — the timer or `/todo continue` — now sends
109
+ the numbered list of open steps rather than the words "continue with the
110
+ remaining todo items", so a plan whose `todo_write` has scrolled out of the
111
+ context window is still followed exactly. Neither path records that text in
112
+ your prompt history any more; it is not something you typed.
113
+
114
+ Under `-p` there is no grace window, because there is nobody there to use it,
115
+ which is precisely why the two counters rather than the human are the
116
+ protection there. `[todo] continuing (3 steps left)` and
117
+ `[todo] 3 steps unfinished` go to stderr, suppressed by `--quiet`, and an
118
+ unfinished plan still never changes the exit code.
119
+
120
+ New surfaces: `/todo follow <notify|auto|off>`; `--todo-follow <mode>`;
121
+ `ARAGON_TODO_FOLLOW`; and `todo.followThrough` in `config.json`. The default
122
+ is `notify`, so a session that does not ask for any of this behaves as it did.
123
+
124
+ - **A plan strip for inline mode.** Inline mode has no fixed frame and so no
125
+ rail, which left every pipe, every `CI=1`, every `TERM=dumb` terminal and
126
+ every window under twelve rows able to see `todo 3/7` but not *which* step was
127
+ running. There is now a one-row strip under the transcript —
128
+ `todo 3/7 > Adding the rail to AppShell +2 done` — windowed on the
129
+ same step the rail would have anchored on. It truncates rather than wrapping
130
+ and is exactly one row at every width, so the composer does not move.
131
+ `--no-todo-panel` hides it along with the rail.
132
+
133
+ ### Changed
134
+
135
+ - `npm run typecheck` now covers the test tree in both packages. `tsconfig.json`
136
+ excludes `__tests__` so the build never emits fixtures, and vitest transpiles
137
+ without typechecking — between the two, a widened required field could break
138
+ ten test files while `npm run build` and `npm test` were both green. Twelve
139
+ such errors had accumulated; all twelve were fixture drift and all twelve are
140
+ repaired, with no suppressions and no production type relaxed to accommodate a
141
+ fixture.
142
+
143
+ - **TODO planning, and a rail to watch it in.** For work with three or more
144
+ distinct steps the agent now keeps a visible plan: it writes a checklist with
145
+ a new `todo_write` tool, marks exactly one item in progress, and ticks it off
146
+ before starting the next. In full-screen mode the list is rendered as a
147
+ right-hand rail about a fifth of the terminal wide, windowed around the step
148
+ being worked on rather than sliced from the top. Ask for something small and
149
+ nothing appears — the prompt tells the model not to plan work it can finish in
150
+ one or two steps, and a one-item list against an empty plan is refused
151
+ outright, so a session that never plans has byte-identical layout to a build
152
+ without this feature.
153
+
154
+ The list is a projection of what the model believes, and that single rule
155
+ decides everything else: `/clear` keeps it (the conversation is still there),
156
+ `/reset` drops it, `/save` writes it and `/resume` restores it — and resuming
157
+ a session that carries no list CLEARS the current one rather than leaving a
158
+ plan on screen whose conversation has just been replaced. A finished plan
159
+ survives to the start of your next message so you get to see `7/7 done`; an
160
+ unfinished one survives "continue" and "now do the rest", then expires after
161
+ three unrelated turns rather than holding a fifth of the screen for the rest
162
+ of the session. A run that ends with items left over produces a notice and
163
+ `/todo continue`; nothing auto-continues on your behalf.
164
+
165
+ "One step at a time" is enforced by structure rather than asked for in a
166
+ prompt: any payload with two in-progress items is repaired down to one, and a
167
+ list with none promotes the first unfinished item. Whatever the model sends,
168
+ the panel has exactly one current row.
169
+
170
+ New surfaces: the `todo_write` tool; `/todo [status|on|off|panel on|off|clear|
171
+ continue]`; `--todo` / `--no-todo` and `--todo-panel` / `--no-todo-panel`;
172
+ `ARAGON_TODO=0`; and `todo.enabled` / `todo.panel` in `config.json` (a third
173
+ key, `todo.followThrough`, arrived with the follow-through entry above).
174
+ `panel` is
175
+ separate from `enabled` on purpose — a screen-reader user wants the planning
176
+ discipline without the column, and the system prompt varies one sentence to
177
+ match. Under `-p` the plan goes to stderr as `[todo] 3/7 <step>` lines,
178
+ suppressed by `--quiet`. Below 80 columns, behind an overlay, in inline mode
179
+ or on a short terminal the rail is not mounted and the counter appears in the
180
+ status bar instead; the transcript keeps at least 62 columns at every width.
181
+
182
+ - **Output token limits that cannot themselves fail a run.** Every model and
183
+ every provider now defaults to 64000 output tokens, and that number is
184
+ configurable from the TUI, from a flag, from `ARAGON_MAX_TOKENS`, and by hand
185
+ in `~/.aragon-agent/config.json`. Leave it alone and it stays 64000.
186
+
187
+ What is new is that the number is an *ambition*. `gpt-4o` caps at 16384 and
188
+ `gemini-1.5-pro` at 8192; sending 64000 to either is an HTTP 400 that ends the
189
+ turn with a raw provider string in the transcript. The cap is now clamped down
190
+ to whatever the target model actually accepts, from a per-model table plus
191
+ whatever the provider's own model list reports. For a model nothing knows — a
192
+ proxy, a `--base-url` endpoint, something that shipped last week — the request
193
+ goes out at 64000, and if the provider objects, `aragon` reads the real ceiling
194
+ out of the error text, repairs the request, sends it exactly once more, and
195
+ remembers the answer for the rest of the session. One warning line; the run
196
+ continues.
197
+
198
+ Two combinations that were a guaranteed 400 on every request are fixed with
199
+ it: `--thinking xhigh` asks for a 65536-token budget while Anthropic requires
200
+ `max_tokens` to be strictly greater than it, and OpenAI's reasoning family
201
+ (`o1`, `o3`, `gpt-5`) rejects the `max_tokens` parameter name outright in
202
+ favour of `max_completion_tokens`.
203
+
204
+ New surfaces: `/max-tokens [<n>|auto|default]`, which with no argument reports
205
+ the setting *and* the effective cap for the live model; an `Effective:` line
206
+ under the settings screen's `Max tokens` field, so a value the model will not
207
+ honour is visible before you save it; `--max-tokens auto`; and
208
+ `aragon config set maxTokens <n|auto|default>`, which echoes the value that was
209
+ actually stored rather than the one you typed.
210
+
211
+ - **Team subagents.** The agent can now hand independent parts of a job to up to
212
+ five short-lived subagents that run in parallel, then read one combined report
213
+ of what each of them found. It decides for itself whether to delegate, so a
214
+ session that never calls the new `task` tool is byte-for-byte the session that
215
+ existed before. On by default; `--no-team` or `team.enabled: false` turns it
216
+ off, and `aragon config set team.maxSubagents <n>` sets the width (1-10; the
217
+ 10 is a hard ceiling no config file can raise).
218
+
219
+ A subagent is a full agent with the same tools and working directory but no
220
+ memory of your conversation, so its brief has to be self-contained. It cannot
221
+ delegate further and it cannot ask you anything. Plan mode and a skill's
222
+ `allowed-tools` ceiling both reach one level down, so delegating is never a
223
+ way around either; `--confirm` queues subagent confirmations one at a time and
224
+ labels each with the subagent that is asking.
225
+
226
+ Subagents can message each other with `team_send` / `team_wait`, delivered by
227
+ attaching the message to the recipient's next tool result rather than
228
+ interrupting it. The limits are deliberate — 6 messages each, one every 15
229
+ seconds, 24 per dispatch — and every refusal is a plain result naming the
230
+ limit rather than an error, because an error invites the retry the limits
231
+ exist to prevent.
232
+
233
+ While a dispatch runs, a roster sits between the transcript and the composer
234
+ and the status bar carries `agents 3/5`; both disappear when it finishes and
235
+ the transcript keeps a card you can expand with `Ctrl+O`. `Esc` aborts every
236
+ subagent and returns the partial report. Under `-p` the transitions go to
237
+ stderr and the subagents' tokens are folded into the `[usage]` footer, so the
238
+ cost readout cannot under-report what the team spent.
239
+
240
+ Full documentation, including the limits table and how team mode interacts
241
+ with plan mode, skills and `--confirm`, is in the README.
242
+
243
+ - **The subagent roster now shows what each subagent is doing, and shows the
244
+ ones that are working.** Where every row used to say `thinking` for minutes at
245
+ a time, it now says `bash: npm test -w cli`, `read: src/api/routes.ts`,
246
+ `waiting for a2`, or the tail of the sentence the subagent is currently
247
+ writing. On a narrow terminal the same row falls back to a file name and a
248
+ program name rather than wrapping, and the elapsed clock keeps its place at
249
+ every width.
250
+
251
+ The five visible rows are now the five that matter: whatever is running comes
252
+ first, then whatever is queued, then the most recent results. Above five
253
+ subagents the old panel showed the five that had finished first and hid
254
+ everything still working behind `+3 more`, which is the opposite of what the
255
+ roster is for. `+3 more` now says how many of the hidden ones are still going.
256
+
257
+ - **A subagent no longer waits two minutes for a message nobody can send.**
258
+ `team_wait` now checks whether anyone could actually answer before it blocks:
259
+ if the teammate it named has already finished, does not exist, or is itself
260
+ waiting in a way that cannot be released in time, it returns straight away and
261
+ says which. Nothing is refused that could still have been answered — including
262
+ by a third teammate further down the chain — and the subagent is told what to
263
+ do instead rather than handed an error.
264
+
265
+ - **A subagent whose very first request dies on a rate limit is retried once.**
266
+ Only a genuine cold start qualifies: no turn completed and no tool ran, so
267
+ there is nothing to undo. It restarts after two seconds, the roster says
268
+ `starting (retry)`, and the report notes `retried 1x`. Pressing `Esc`, a
269
+ timeout, or any subagent that had already begun work is never retried.
270
+
271
+ ### Changed
272
+
273
+ - **`"maxTokens": null` in `config.json` now means AUTO** — use each model's own
274
+ ceiling, never above 64000. It previously resolved to 64000 by accident (the
275
+ layered resolver skipped `null`), and there was no way to express AUTO through
276
+ any supported write path. If you have a `null` there today, the only difference
277
+ is a downward clamp on models whose real ceiling is below 64000 — the direction
278
+ that prevents failures rather than causing them. Absent still means 64000, and
279
+ an explicit number still means that number.
280
+
281
+ - **`config.json` holds settings again.** The prompts you type are no longer
282
+ stored in it. They move to `~/.aragon-agent/prompt-history.jsonl` — one JSON
283
+ object per line, `0600` on POSIX — and the submit counter and the "notice
284
+ already shown" flag move to `~/.aragon-agent/state.json`. `↑` and `↓` behave
285
+ exactly as before.
286
+
287
+ Two things get better. Opening `config.json` to change your model no longer
288
+ means scrolling past a transcript of your own typing, and copying it to
289
+ another machine no longer carries your prompts along. And submitting a message
290
+ no longer rewrites the file that holds your API keys: `config.json` is written
291
+ when you change a setting, and at no other time.
292
+
293
+ **Your history and counters are migrated automatically, once, at the next
294
+ launch.** Nothing is printed, because nothing changes for you. The dead
295
+ `recentModels` key — which nothing has ever written — is dropped.
296
+
297
+ If you go back to 0.5.x after upgrading, that version does not know about the
298
+ new file and `↑` will look empty. Nothing has been lost: the entries are still
299
+ in `prompt-history.jsonl`, and upgrading again brings them back.
300
+
301
+ ### Added
302
+
303
+ - **`aragon history`** — `path`, `list` (`-n`, `--json`) and `clear --yes` for
304
+ the prompt history, alongside the existing `aragon logs` commands. Entries are
305
+ stored verbatim, so `clear` is how you erase them; `aragon config set
306
+ historyEnabled false` stops new ones being recorded without deleting or hiding
307
+ what is already there.
308
+
309
+ - **The mouse wheel scrolls what is under the pointer.** In full-screen mode the
310
+ wheel now scrolls the transcript three rows per notch (a page with `Shift`),
311
+ scrolls an open overlay when the pointer is over one, and steps prompt history
312
+ one entry per notch when the pointer is over the input box — the same code
313
+ path `↑` / `↓` use, so it inherits the rule that an in-progress draft is never
314
+ overwritten. A slim rail on the viewport's right edge shows where you are in
315
+ the conversation.
316
+
317
+ **This fixes a destructive bug.** Previously the wheel recalled prompt history
318
+ no matter where the pointer was, because the alternate screen makes terminals
319
+ translate each notch into arrow keys. Wheeling while composing a message
320
+ silently replaced the draft with an old prompt, and nothing scrolled.
321
+
322
+ **Selecting text with the mouse now requires `Shift`+drag** in most terminals.
323
+ That is the standard convention for "an application is tracking the mouse" and
324
+ it applies to everyone, including people who never scroll with the wheel — so
325
+ the first session says so once, in the transcript, and never again. Turn the
326
+ whole feature off with `--no-mouse`, `ARAGON_MOUSE=0`, or
327
+ `aragon config set mouse false`; the wheel then does nothing rather than
328
+ reverting to the old behaviour. Inline mode (`--no-fullscreen`) is untouched:
329
+ your terminal's own scrollback already does the right thing there.
330
+
331
+ Under `tmux` with `mouse on`, tmux keeps the wheel for itself and the app
332
+ never sees it. `set -g mouse off` hands it back.
333
+
334
+ ### Changed
335
+
336
+ - **Your files moved to `~/.aragon-agent/`.** Config, sessions, installed skills
337
+ and the usage counters now live in one directory in your home — on Windows
338
+ `C:\Users\<you>\.aragon-agent\`, and the same path on macOS and Linux. They
339
+ used to be split across `%APPDATA%\aragon-agent-nodejs\Config` and
340
+ `%LOCALAPPDATA%\aragon-agent-nodejs\Data` (or the XDG equivalents), which are
341
+ correct locations and terrible answers to "where do I change the model?".
342
+
343
+ **The move happens once, automatically, on first launch, and prints a line on
344
+ stderr when it does.** Nothing is deleted: `config.json` is COPIED rather than
345
+ moved, and the old directories are left where they are, so reinstalling 0.5.0
346
+ remains lossless. `aragon config home` prints the new location and names the
347
+ old ones. Once you are satisfied, you can delete them yourself.
348
+
349
+ `ARAGON_HOME` relocates the whole tree. It has to be a real environment
350
+ variable — the path is resolved before any `.env` is read, so putting it in a
351
+ `.env` will not work. `aragon config home` always prints what is actually in
352
+ use.
353
+
354
+ ### Added
355
+
356
+ - **Logging.** Records go to `~/.aragon-agent/logs/aragon-<date>.log` as JSON
357
+ Lines: startup and exit, config writes, turn boundaries with token counts,
358
+ tool names with durations, skill loads, and every uncaught error. Files rotate
359
+ by day and by size (`log.maxFileBytes`, default 5 MiB) and the oldest beyond
360
+ `log.maxFiles` (default 10) are deleted.
361
+
362
+ **`info`, the default, records no conversation content**, so attaching a log
363
+ to a bug report is safe. `--log-level debug` (or `--verbose`) adds prompts,
364
+ replies and tool arguments truncated to `log.previewChars`; `trace` adds them
365
+ in full. Those two write what you typed — check before sharing one.
366
+
367
+ API keys are removed at every level by two independent passes: fields whose
368
+ name looks like a credential are blanked whatever they hold, and every string
369
+ is scanned both for known key formats and for the literal keys this process is
370
+ holding — which is what covers a custom endpoint whose key looks like nothing
371
+ in particular. `log.redactSecrets false` turns both off and warns you on
372
+ stdout when you set it.
373
+
374
+ Nothing is ever uploaded. There is no network path out of this subsystem.
375
+
376
+ New commands: `aragon logs path | list | tail [-n N] [--follow] [--level lv]
377
+ [--json] | clear --yes | open`, and `/logs` inside the TUI. New flags:
378
+ `--log-level`, `--verbose`, `--log-file` / `--no-log-file`, `--log-dir`. New
379
+ environment variables: `ARAGON_LOG_LEVEL`, `ARAGON_LOG_FILE`, `ARAGON_LOG_DIR`
380
+ — these three, unlike `ARAGON_HOME`, can come from a `.env`.
381
+
382
+ - **`aragon config get <key>` / `list [--json]` / `edit` / `home`.** `get` and
383
+ `list` mask every secret, `--json` included. `edit` opens `config.json` in
384
+ `$VISUAL` / `$EDITOR` (`notepad` on Windows), takes a `config.json.bak` first,
385
+ and re-parses on exit — an invalid edit is reported immediately, and the
386
+ backup is named in the message.
387
+
388
+ - **`/reload`** re-reads `config.json` into the running session, for when you
389
+ have edited it in another window. Refused while a run is in progress: swapping
390
+ the model mid-turn would let the second half of an answer come from different
391
+ settings than the first, with nothing afterwards able to explain the result.
392
+
393
+ - **Log level in the settings screen**, alongside provider / model / thinking.
394
+ The rest of the log settings — and `redactSecrets` above all — stay
395
+ command-line-only, so the one switch that can put credentials on disk cannot
396
+ be flipped with an arrow key.
397
+
398
+ ### Fixed
399
+
400
+ - **A malformed `config.json` no longer resets everything in silence.** A stray
401
+ comma used to send the model, theme, timeouts, skills and (as far as you could
402
+ tell) your API key back to defaults, with nothing anywhere explaining it. The
403
+ fallback is unchanged — a bad config still never stops the CLI from starting —
404
+ but it now says so, and records why.
405
+
406
+ - **Ctrl+C now flushes pending log records in every mode.** The signal handlers
407
+ only existed in the full-screen branch, so `-p`, the inline renderer and every
408
+ subcommand took Node's default termination, which does not run exit handlers.
409
+
410
+ ### Added
411
+
412
+ - **Plan mode.** `Shift+Tab` toggles between `BUILD` (everything as before) and
413
+ `PLAN`, a read-only research-and-design posture. `/plan [on|off|status]` is a
414
+ first-class equivalent for terminals that swallow `CSI Z`, and `--plan` /
415
+ `--no-plan` / `ARAGON_PLAN=1` / `planModeDefault` cover the startup case.
416
+
417
+ In `PLAN`, `write_file`, `edit_file`, `bash`, `skill_install` and
418
+ `skill_create` are refused **at the tool boundary**, so read-only is a
419
+ property of the wiring rather than a promise in a prompt. `bash` is refused in
420
+ full, `git status` included: a shell string cannot be classified reliably, and
421
+ a gate that is right most of the time is worse than one that is always right,
422
+ because you stop trusting the badge. The refusal names `read_file` / `glob` /
423
+ `grep` as the alternatives.
424
+
425
+ Two tools exist only while a human is attached. `ask_user` renders a
426
+ keyboard-driven wizard - 1-5 questions, 2-4 options each, exactly one marked
427
+ `RECOMMENDED`, plus an `Other...` free-text option - where pressing `Enter`
428
+ through the wizard accepts every recommendation. `submit_plan` renders the
429
+ plan as a scrollable card: `a` approves, `r` sends written feedback (`<-`
430
+ returns to the card), `Esc` dismisses. **Approving flips the session to
431
+ `BUILD` immediately and the same run continues into implementation.**
432
+
433
+ Dismissing a plan asks for a better one rather than stopping - the agent is
434
+ told to refine and resubmit - so the way out of a run is `Esc` twice: the
435
+ first closes the card, the second aborts the run.
436
+
437
+ Toggling mid-run is asymmetric on purpose: `build -> plan` applies at once,
438
+ `plan -> build` is deferred to the end of the run (the status bar shows
439
+ `PLAN -> BUILD` meanwhile) so a run launched under a read-only guarantee
440
+ cannot start writing files because of one stray keypress.
441
+
442
+ `aragon -p --plan "..."` registers no question or plan tool - there is nobody
443
+ to ask - but the read-only gate still applies, so it means "tell me how you
444
+ would do this, and do not touch my repository".
445
+
446
+ - Three flat config keys: `planModeDefault` (default `false`),
447
+ `planModeMaxAskRounds` (default `4`, clamped `[1, 10]`) and
448
+ `planModeHumanTimeoutMs` (default `1800000`, clamped `[60000, 7200000]`). All
449
+ three are settable with `aragon config set`. Additive, as always: a config
450
+ file written by an earlier version loads unchanged.
451
+
452
+ ### Fixed
453
+
454
+ - A `--confirm` prompt no longer races the idle watchdog. Taking longer than
455
+ `idleTimeoutMs` over `Proceed? (y/N)` used to abort the run with no
456
+ explanation; every human wait now suspends the watchdog and restarts it in a
457
+ `finally`.
458
+
459
+ - Honor an explicit `NODE_TLS_REJECT_UNAUTHORIZED=0` setting in the CLI and the
460
+ official npm release workflow while hiding only Node's standard insecure-TLS
461
+ warning. Other process warnings remain visible.
462
+
463
+ ## 0.5.0
464
+
465
+ ### Breaking
466
+
467
+ - **The package is renamed `@argon-agent/cli` → `@aragon-agent/cli`.** The brand
468
+ was always meant to be *Aragon*, matching AragonMesh; the missing `a` was a
469
+ typo that reached the registry. Install with:
470
+
471
+ ```
472
+ npm uninstall -g @argon-agent/cli
473
+ npm install -g @aragon-agent/cli
474
+ ```
475
+
476
+ `@argon-agent/cli` is deprecated and receives no further releases. **The
477
+ executable is still `aragon`** — the command you type does not change.
478
+
479
+ - **Environment variables are `ARAGON_*`, not `ARGON_*`.** There is no
480
+ compatibility fallback: `ARGON_MODEL`, `ARGON_PROVIDER`, `ARGON_BASE_URL`,
481
+ `ARGON_THINKING`, `ARGON_MAX_TOKENS`, `ARGON_THEME`, `ARGON_FULLSCREEN`,
482
+ `ARGON_SKILLS`, `ARGON_SKILLS_DISABLED`, `ARGON_SKILLS_PATH` and
483
+ `ARGON_REDUCED_MOTION` are all ignored from this release on. Rename them in
484
+ your shell profile and CI. Provider keys (`ANTHROPIC_API_KEY`,
485
+ `OPENAI_API_KEY`, `GOOGLE_API_KEY`, `GEMINI_API_KEY`) are untouched.
486
+
487
+ - **The project-level skills directory is `.aragon/skills`, not
488
+ `.argon/skills`.** This one lives in your repository, so rename it yourself:
489
+
490
+ ```
491
+ git mv .argon .aragon
492
+ ```
493
+
494
+ A config file that already persisted the old default keeps working — an
495
+ explicitly saved `skills.projectDirs` still wins over the default — but the
496
+ shipped default is now `['.aragon/skills', '.claude/skills']`. Update it with
497
+ `aragon config set` if you want the new default.
498
+
499
+ ### Added
500
+
501
+ - **Automatic migration of your user-level state.** On first run, 0.5.0 moves
502
+ the `env-paths` config and data directories from `argon-agent` to
503
+ `aragon-agent` — your API key, sessions and installed skills come with it, and
504
+ each installed skill's `.argon-skill.json` manifest is renamed to
505
+ `.aragon-skill.json` so `skills update` and `skills uninstall` still recognise
506
+ it. The migration prints one line to **stderr**, runs once, and is skipped
507
+ entirely if the new directory already exists. If it fails for any reason the
508
+ CLI still starts; the old directory is never deleted when a cross-volume copy
509
+ was needed.
510
+
511
+ - The opening wordmark now reads `ARAGON` and is 52 columns wide (was 44).
512
+ Terminals between 52 and 55 columns show the single-line banner rather than a
513
+ clipped wordmark.
514
+
515
+ - **Skills.** A skill is a directory holding a `SKILL.md` (YAML frontmatter +
516
+ Markdown body) plus optional `reference/`, `scripts/` and `assets/`. Skills
517
+ reach the model through three levels of progressive disclosure: a name +
518
+ one-line "when to use" catalog in the system prompt (≤ 6 000 bytes total),
519
+ the full body only when the model calls the `skill` tool, and bundled files
520
+ only when it reads them with `read_file` / `bash`. A skill therefore costs a
521
+ line of context rather than its whole body. How many fit in Level 1 depends on
522
+ description length and language — roughly 30 with terse English descriptions,
523
+ roughly 10 with Chinese ones at the character cap; past that the catalog
524
+ truncates and `skill_find` covers the remainder.
525
+ - Four model-facing tools: `skill` (load), `skill_find` (search installed
526
+ skills), `skill_install` (install from a local directory, git repo, or https
527
+ `SKILL.md` / `.zip`) and `skill_create` (author a new one from a procedure the
528
+ agent just worked out).
529
+ - **`aragon skills update <name> | --all`**, with `--dry-run`, `--force` and
530
+ `--check`. Re-fetches from the source recorded in the install manifest,
531
+ preserving `installedAt` and recording `updatedAt` / `previousVersion`. Refuses
532
+ before downloading anything when the installed copy has local edits, and
533
+ re-validates the source against the *current* `skills.allowedHosts` rather than
534
+ the one in force at install time. Not exposed to the model.
535
+ - **Catalog ranking.** Level 1 entries are ordered by scope, then by how recently
536
+ and often each skill was used, so truncation drops what you do not use rather
537
+ than what sorts last alphabetically. With no usage data the order is unchanged.
538
+ - **`skill_find`**, advertised in the prompt only when the catalog actually
539
+ truncated. Searches installed skills by name, description and keyword; never
540
+ reaches the network, never returns `activation: manual` skills, and tells the
541
+ model to ask for a source rather than invent one when nothing matches.
542
+ - **Cross-process install lock.** Install / create / remove / update take a
543
+ per-directory advisory lock, closing a race in which two concurrent installs
544
+ could interleave their atomic-replace steps and delete a skill with no error.
545
+ Self-expires after 60 s; waits at most 5 s; only ever released by its owner.
546
+ - **Load-time integrity.** Discovery re-checks `SKILL.md` against the sha256
547
+ recorded at install, at no extra I/O. `skills.integrity` selects
548
+ `off` / `warn` (default) / `strict`.
549
+ - **Local usage counters** at `<data>/skill-usage.json` — skill name, count and
550
+ timestamp only, never transmitted, disabled with `skills.usageTracking=false`.
551
+ Automatically injected `activation: always` skills are not counted.
552
+ - Config keys `skills.integrity` and `skills.usageTracking`; `aragon skills list
553
+ --sort=recent` and `/skills list --sort=recent`.
554
+ - Every usable skill also becomes a slash command: `/<skill-name> [args]`, with
555
+ `$ARGUMENTS` / `$1..$9` substitution. On a name clash the built-in command
556
+ always wins and the skill is reachable as `/skill:<name>`.
557
+ - `/skills` management: `list`, `info`, `install`, `remove`, `enable`,
558
+ `disable`, `reload`, `create`, `trust`, `untrust`.
559
+ - `aragon skills …` non-interactive equivalents plus `path` and `doctor`.
560
+ Exit codes follow `config set`: `0` ok, `1` run-time failure, `2` usage.
561
+ - Four discovery scopes in ascending precedence: bundled (`<pkg>/skills`), user
562
+ (`<data>/skills`), project (`<cwd>/.aragon/skills` and, read-only,
563
+ `<cwd>/.claude/skills` for Claude Code interop), and `ARAGON_SKILLS_PATH`.
564
+ - New flags `--no-skills`, `--skill <name>` (repeatable) and `--skills-yes`;
565
+ env `ARAGON_SKILLS`, `ARAGON_SKILLS_PATH`, `ARAGON_SKILLS_DISABLED`; config keys
566
+ `skills.enabled`, `skills.requireApproval`, `skills.catalogMaxBytes`,
567
+ `skills.bodyMaxBytes`.
568
+ - One bundled skill, `skill-creator`, documenting how to write a good one.
569
+ - New runtime dependency: `fflate` (~30 KB, MIT, zero transitive deps) for zip
570
+ extraction. `@aragon-agent/core` gains no dependency.
571
+ - **Release tooling for the scope change.** `npm run verify:brand` scans every
572
+ file that `npm pack` would put in the tarball — README and `dist/` included —
573
+ and blocks the release on any surviving `argon` reference, with only the four
574
+ documented exceptions (the two CHANGELOGs and the legacy-state migration
575
+ module, which hold the old names by definition). `packages/cli` also gains a
576
+ `prepublishOnly: npm run build`, so a publish that bypasses
577
+ `publish-latest.ps1` can no longer ship a `dist/` that is out of step with the
578
+ sources. `deprecate-legacy.ps1` retires `@argon-agent/*` on the registry, and
579
+ refuses to do so until the replacements are actually published.
580
+
581
+ ### Changed
582
+
583
+ - The globally installed executable is now `aragon`. The previous `argon` and
584
+ `argon-agent` aliases are no longer installed.
585
+ - `config/store.ts` now deep-merges the `skills` section on both read and write,
586
+ the same treatment `apiKeys` already received. Without it a partial patch such
587
+ as the one `/skills disable` sends would replace the whole section and
588
+ silently discard `trustedProjectDirs`, `allowedHosts` and `requireApproval`.
589
+ - `slashSuggestions` accepts `-` and `:`, so kebab-case and `skill:`-namespaced
590
+ commands autocomplete. Previously `/my-sk` produced no popup at all.
591
+ - `AgentController` now has a single `agent.setSystemPrompt()` call site, so a
592
+ `/cwd` change can no longer drop the skill catalog out of the prompt.
593
+ - With skills off or none installed, the system prompt and the 7-tool array are
594
+ byte-identical to the previous release.
595
+ - Added a repository-level PowerShell release workflow that automatically
596
+ updates CLI and Core versions, synchronizes their dependency and lockfile,
597
+ verifies both tarballs, and publishes them in dependency order.
598
+
599
+ ### Security
600
+
601
+ - Installing a skill requires an explicit human approval that **probes for a
602
+ human first and refuses when there is none**. Under `-p` there is no TUI and
603
+ therefore no approver, so `skill_install` is refused with an actionable
604
+ message rather than writing a third-party directory unattended. Use
605
+ `--skills-yes` (or `skills.requireApproval=false`) to opt out deliberately.
606
+ - Project skill directories require a one-time trust confirmation before they
607
+ are loaded — cloning an unfamiliar repository does not grant it the ability
608
+ to inject instructions into your session.
609
+ - Git is invoked only via `execFile` with an argv array and `shell: false`, and
610
+ owner / repo / ref / subdirectory fragments are whitelisted and refused if
611
+ they begin with `-`. A leading dash matters even with a pure argv array:
612
+ `--upload-pack=<program>` makes git execute that program.
613
+ - Zip extraction is streamed and gated on **actually written** bytes, per-entry
614
+ size, compression ratio and entry count, all of which can abort mid-archive.
615
+ The size a zip *declares* is written by whoever built it and is never trusted.
616
+ Path traversal, absolute entries, symlinks and Windows device names are
617
+ refused, and a rejected archive is removed rather than left half-extracted.
618
+ - Network fetches are `https:` only, restricted to `skills.allowedHosts`,
619
+ re-checked on every redirect (max 3), size-capped, and refuse IP literals and
620
+ loopback.
621
+ - Nothing a skill ships is executed at install time, and the executable bit is
622
+ not preserved. Scripts run only when the model invokes `bash` explicitly.
623
+ There is no sandbox: approval blocks *silent* installation, it does not make
624
+ a skill you approved safe.
625
+
626
+ ## 0.3.0
627
+
628
+ A full-screen TUI release. `@argon-agent/core` is untouched, no new runtime
629
+ dependency is added, and the headless/print contract, exit codes, and
630
+ slash-command semantics are unchanged. The 0.2.0 inline renderer remains
631
+ available in full via `--no-fullscreen`.
632
+
633
+ ### Added
634
+
635
+ - **Full-screen mode (default).** `aragon` now takes over the terminal's
636
+ alternate screen buffer — the same mechanism `vim` / `htop` / `lazygit` use.
637
+ Your shell history is covered, not erased, and comes back untouched on exit.
638
+ The frame is a fixed `rows - 1` tall, so **the composer and the status bar sit
639
+ at the physical bottom of the screen from the very first frame**: empty
640
+ session, long session, mid-scroll, or overlay open.
641
+ - **Brand region.** A six-row gradient ASCII wordmark on a roomy empty session,
642
+ degrading to a banner, then a single-line bar, then a bare wordmark as space
643
+ runs out. Row 1 always begins with the brand glyph.
644
+ - **Self-drawn scrolling.** `PgUp` / `PgDn` by the page, `Shift+↑` / `Shift+↓` by
645
+ the line. The viewport auto-follows new output while pinned to the bottom;
646
+ scrolling away shows `↑N` in the status bar plus a "N new lines" hint, and
647
+ submitting a message always re-pins.
648
+ - **Exit replay.** After leaving the alternate screen the session is replayed
649
+ into the normal buffer as plain, colorless text, so the conversation does not
650
+ evaporate with the screen. Turn it off with `--no-exit-transcript`.
651
+ - **New flags** `--fullscreen` / `--no-fullscreen` / `--no-exit-transcript`, the
652
+ env var `ARGON_FULLSCREEN=0|1`, and the config keys `fullscreen`,
653
+ `exitTranscript`, and `transcriptWindow`.
654
+ - **Automatic downgrade.** A non-TTY stdout, `TERM=dumb`, CI, and terminals under
655
+ 12 rows / 40 columns fall back to the inline renderer. Only the non-TTY gate is
656
+ un-overridable — `--fullscreen` beats the rest.
657
+
658
+ ### Changed
659
+
660
+ - The status bar lost its round border and is now exactly one row; it had been
661
+ spending an eighth of a 24-row terminal framing a single line of text.
662
+ - The toast strip holds a fixed row in full-screen mode, so the transcript no
663
+ longer jumps as toasts appear and expire.
664
+ - The composer is a rounded frame whose border color reports state (idle, has a
665
+ draft, running, blurred by an overlay), with the completion popup above it.
666
+ - `Ctrl+L` repaints the frame instead of writing a clear sequence. Ink dedupes
667
+ identical output at two separate gates, so under a fixed frame the old
668
+ approach erased the screen and then declined to redraw it.
669
+ - `Shift+↑` / `Shift+↓` no longer recall prompt history — they scroll.
670
+ - Full-screen mode routes `console.*` into the transcript as notices rather than
671
+ letting Ink write them straight to stdout, which corrupts the frame's line
672
+ accounting.
673
+
674
+ ### Known trade-offs
675
+
676
+ - The terminal's native scrollback and mouse wheel do not scroll the transcript
677
+ in full-screen mode; use `PgUp` / `PgDn`, or run with `--no-fullscreen`.
678
+ - Mouse tracking is deliberately left off: enabling it costs text selection and
679
+ copy in most terminals.
680
+ - Should a crash ever strand your terminal on the alternate screen, `reset`
681
+ restores it. Four independent restore paths exist to prevent that: normal
682
+ exit, `process.exit`, `SIGINT` / `SIGTERM` / `SIGHUP`, and Ink's own signal
683
+ handling.
684
+
685
+ ## 0.2.0
686
+
687
+ A design-elevation & HCI-hardening release. No breaking changes: `@argon-agent/core`
688
+ is untouched, no new runtime dependency is added, and the headless/print contract,
689
+ exit codes, config keys, and slash-command semantics from 0.1.0 are unchanged.
690
+
691
+ ### Added
692
+
693
+ - **Real theming engine.** Distinct `dark` / `light` palettes with an `auto`
694
+ resolution (`auto → dark`), color degradation across terminal depth
695
+ (truecolor → 256 → 16 → monochrome), and an ASCII glyph fallback for terminals
696
+ without Unicode. Honors `NO_COLOR`, `FORCE_COLOR`, `--no-color`, and
697
+ `TERM=dumb`. Switch live with `/theme <auto|dark|light>` (persisted).
698
+ - **Elegant chrome.** A gradient wordmark header that collapses to a slim sticky
699
+ bar after the first turn, a first-run **Welcome / empty-state** card, and a
700
+ status bar with a colored **context gauge** (threshold colors), a **tokens/sec**
701
+ read-out while running, and a contextual hint.
702
+ - **Legible tool output.** Colored unified diffs (green adds / red removes) and
703
+ per-tool rich previews (`edit_file`/`write_file`/`read_file`/`bash`/`list_dir`/
704
+ `glob`). Long previews collapse to 8 lines and expand with `Ctrl+O` or
705
+ `/expand [n]`.
706
+ - **Autocomplete.** A slash-command palette and `@file` path completion popup
707
+ (`Tab`/`→` to complete, `Up`/`Down` to move, `Esc` to close).
708
+ - **Full line editing.** Home/End, word jump/delete, kill-to-start/end, and
709
+ multi-line vertical cursor navigation, with prompt-history recall at the edges.
710
+ Unknown control/escape sequences are dropped instead of inserted.
711
+ - **Reliability under load.** Ink `<Static>` finalization for settled entries and
712
+ a streaming delta coalescer, so long/fast sessions stay flicker-free.
713
+ - **Calm feedback.** Ephemeral, auto-dismissing **toasts** for transient acks;
714
+ the transcript keeps only durable content (messages, tool cards, run errors).
715
+ - `reducedMotion` config (also `ARGON_REDUCED_MOTION`; implied by `--no-color`)
716
+ replaces spinners with a static glyph.
717
+
718
+ ### Changed
719
+
720
+ - History scrollback now uses the **native terminal scrollback** that `<Static>`
721
+ prints into (this supersedes the never-implemented `PgUp`/`PgDn` promise).
722
+
723
+ ## 0.1.0
724
+
725
+ Initial release — a Claude-Code / Codex-style interactive terminal UI (TUI) on
726
+ top of `@argon-agent/core`.
727
+
728
+ ### Added
729
+
730
+ - **Interactive TUI** (React + Ink): gradient header, streaming transcript with
731
+ markdown + syntax highlighting, collapsible thinking blocks, live tool-call
732
+ cards, a status bar (model / context % / tokens / cost / elapsed), and modal
733
+ overlays (settings, model picker, help, confirm).
734
+ - **Built-in toolset** wired into the core agent at full permission:
735
+ `read_file`, `write_file`, `edit_file`, `list_dir`, `glob`, `grep`, `bash`.
736
+ - **Layered configuration** (defaults → user file → env/`.env` → flags) with
737
+ live in-TUI editing of provider / model / base URL / API keys / thinking level
738
+ / max tokens. Secrets are masked and the config file is written `0600` on POSIX.
739
+ - **One-shot / print mode** (`argon -p`) for scripting and piping, plus
740
+ `argon config` / `argon config set` / `argon config path` / `argon models`.
741
+ - **Session control**: abort (Esc), steer-while-running, follow-up queue,
742
+ double-Ctrl-C exit, `/save` / `/resume` JSON sessions.
743
+ - **Timeout invariant** (`idleTimeout ≥ toolTimeout`) so a long single tool run
744
+ is never killed by the idle watchdog.
745
+ - **Never-silent failures**: pre-flight API-key validation, error-StreamEvent
746
+ rendering, and a guard that surfaces a swallowed agent error instead of a
747
+ blank no-op (headless exits `1`/`2` accordingly).