@aragon-agent/cli 0.5.4 → 0.5.6

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