@aragon-agent/cli 0.6.2 → 0.6.4
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.
- package/CHANGELOG.md +321 -0
- package/README.md +297 -2
- package/dist/agent/controller.d.ts +193 -1
- package/dist/agent/controller.js +475 -2
- package/dist/agent/headless.d.ts +8 -0
- package/dist/agent/headless.js +47 -0
- package/dist/agent/reducer.d.ts +189 -0
- package/dist/agent/reducer.js +301 -2
- package/dist/agent/system-prompt.d.ts +14 -0
- package/dist/agent/system-prompt.js +2 -0
- package/dist/cli.js +297 -16
- package/dist/commands/builtins.js +165 -24
- package/dist/commands/registry.d.ts +27 -0
- package/dist/compaction/archive.d.ts +175 -0
- package/dist/compaction/archive.js +267 -0
- package/dist/compaction/child.d.ts +97 -0
- package/dist/compaction/child.js +118 -0
- package/dist/compaction/command.d.ts +41 -0
- package/dist/compaction/command.js +355 -0
- package/dist/compaction/compactor.d.ts +302 -0
- package/dist/compaction/compactor.js +810 -0
- package/dist/compaction/digest.d.ts +62 -0
- package/dist/compaction/digest.js +164 -0
- package/dist/compaction/limits.d.ts +165 -0
- package/dist/compaction/limits.js +172 -0
- package/dist/compaction/pressure.d.ts +135 -0
- package/dist/compaction/pressure.js +167 -0
- package/dist/compaction/summarize-call.d.ts +70 -0
- package/dist/compaction/summarize-call.js +86 -0
- package/dist/compaction/summary-prompt.d.ts +85 -0
- package/dist/compaction/summary-prompt.js +197 -0
- package/dist/compaction/tail-budget.d.ts +52 -0
- package/dist/compaction/tail-budget.js +67 -0
- package/dist/compaction/types.d.ts +215 -0
- package/dist/compaction/types.js +22 -0
- package/dist/compaction/wiring.d.ts +264 -0
- package/dist/compaction/wiring.js +577 -0
- package/dist/config/app-paths.d.ts +14 -0
- package/dist/config/app-paths.js +16 -0
- package/dist/config/cli-commands.d.ts +41 -0
- package/dist/config/cli-commands.js +77 -1
- package/dist/config/env.d.ts +5 -2
- package/dist/config/env.js +140 -3
- package/dist/config/load.d.ts +42 -0
- package/dist/config/load.js +101 -1
- package/dist/config/schema.d.ts +244 -0
- package/dist/config/schema.js +170 -0
- package/dist/config/store.js +37 -1
- package/dist/config/ui-state.d.ts +28 -1
- package/dist/config/ui-state.js +9 -0
- package/dist/exec/events.d.ts +50 -1
- package/dist/exec/runner.js +42 -0
- package/dist/input/limits.d.ts +72 -0
- package/dist/input/limits.js +63 -0
- package/dist/input/mouse-events.d.ts +31 -5
- package/dist/input/mouse-events.js +86 -27
- package/dist/input/paste-parse.d.ts +71 -0
- package/dist/input/paste-parse.js +95 -0
- package/dist/input/stdin-filter.d.ts +81 -0
- package/dist/input/stdin-filter.js +379 -0
- package/dist/logging/install.d.ts +53 -1
- package/dist/logging/install.js +81 -1
- package/dist/logging/logger.d.ts +1 -1
- package/dist/proc/classify.d.ts +52 -0
- package/dist/proc/classify.js +143 -0
- package/dist/proc/kill-tree.d.ts +42 -0
- package/dist/proc/kill-tree.js +119 -0
- package/dist/proc/limits.d.ts +84 -0
- package/dist/proc/limits.js +84 -0
- package/dist/proc/log-ring.d.ts +68 -0
- package/dist/proc/log-ring.js +102 -0
- package/dist/proc/prompt.d.ts +24 -0
- package/dist/proc/prompt.js +49 -0
- package/dist/proc/readiness.d.ts +102 -0
- package/dist/proc/readiness.js +219 -0
- package/dist/proc/supervisor.d.ts +103 -0
- package/dist/proc/supervisor.js +465 -0
- package/dist/proc/types.d.ts +175 -0
- package/dist/proc/types.js +15 -0
- package/dist/session/persist.js +55 -1
- package/dist/team/report.js +7 -1
- package/dist/team/runtime.d.ts +10 -0
- package/dist/team/runtime.js +7 -0
- package/dist/team/subagent.d.ts +31 -1
- package/dist/team/subagent.js +42 -15
- package/dist/team/types.d.ts +8 -0
- package/dist/tools/bash-tool.d.ts +51 -2
- package/dist/tools/bash-tool.js +321 -51
- package/dist/tools/fs-tools.d.ts +17 -0
- package/dist/tools/index.d.ts +55 -2
- package/dist/tools/index.js +39 -1
- package/dist/tools/proc-tools.d.ts +25 -0
- package/dist/tools/proc-tools.js +102 -0
- package/dist/ui/ActivityLine.d.ts +19 -1
- package/dist/ui/ActivityLine.js +10 -2
- package/dist/ui/App.d.ts +62 -2
- package/dist/ui/App.js +546 -16
- package/dist/ui/Composer.d.ts +66 -1
- package/dist/ui/Composer.js +50 -6
- package/dist/ui/PromptInput.d.ts +82 -3
- package/dist/ui/PromptInput.js +232 -49
- package/dist/ui/StatusBar.d.ts +59 -0
- package/dist/ui/StatusBar.js +16 -4
- package/dist/ui/TeamPanel.js +7 -1
- package/dist/ui/Transcript.d.ts +21 -1
- package/dist/ui/Transcript.js +61 -3
- package/dist/ui/clipboard.d.ts +52 -0
- package/dist/ui/clipboard.js +91 -0
- package/dist/ui/composer-limits.d.ts +31 -0
- package/dist/ui/composer-limits.js +50 -0
- package/dist/ui/composer-rows.d.ts +73 -0
- package/dist/ui/composer-rows.js +201 -0
- package/dist/ui/editor-reducer.d.ts +37 -0
- package/dist/ui/editor-reducer.js +88 -12
- package/dist/ui/entries/CompactionCard.d.ts +75 -0
- package/dist/ui/entries/CompactionCard.js +158 -0
- package/dist/ui/entries/ServiceCard.d.ts +66 -0
- package/dist/ui/entries/ServiceCard.js +116 -0
- package/dist/ui/entries/UserEntry.d.ts +17 -3
- package/dist/ui/entries/UserEntry.js +34 -5
- package/dist/ui/frame-differ.d.ts +46 -0
- package/dist/ui/frame-differ.js +94 -10
- package/dist/ui/gauge.d.ts +16 -1
- package/dist/ui/gauge.js +25 -6
- package/dist/ui/glyphs.d.ts +11 -0
- package/dist/ui/glyphs.js +2 -0
- package/dist/ui/layout/ScrollViewport.d.ts +43 -6
- package/dist/ui/layout/ScrollViewport.js +128 -21
- package/dist/ui/layout/budget.d.ts +44 -9
- package/dist/ui/layout/budget.js +42 -10
- package/dist/ui/layout/follow-state.d.ts +137 -0
- package/dist/ui/layout/follow-state.js +150 -0
- package/dist/ui/layout/virtual-window.d.ts +11 -0
- package/dist/ui/layout/virtual-window.js +85 -1
- package/dist/ui/overlays/HelpOverlay.js +9 -1
- package/dist/ui/overlays/PlanReviewOverlay.js +10 -2
- package/dist/ui/overlays/QuestionOverlay.js +5 -1
- package/dist/ui/overlays/SettingsScreen.d.ts +47 -1
- package/dist/ui/overlays/SettingsScreen.js +74 -2
- package/dist/ui/palettes.d.ts +16 -0
- package/dist/ui/palettes.js +6 -0
- package/dist/ui/paste-frames.d.ts +87 -0
- package/dist/ui/paste-frames.js +112 -0
- package/dist/ui/paste-tokens.d.ts +90 -0
- package/dist/ui/paste-tokens.js +147 -0
- package/dist/ui/screen.d.ts +38 -0
- package/dist/ui/screen.js +113 -8
- package/dist/ui/selection/highlight.d.ts +39 -0
- package/dist/ui/selection/highlight.js +64 -0
- package/dist/ui/selection/screen-mirror.d.ts +24 -0
- package/dist/ui/selection/screen-mirror.js +35 -0
- package/dist/ui/selection/selection-controller.d.ts +88 -0
- package/dist/ui/selection/selection-controller.js +282 -0
- package/dist/ui/selection/selection.d.ts +90 -0
- package/dist/ui/selection/selection.js +223 -0
- package/dist/ui/stdout-frame-writer.d.ts +33 -0
- package/dist/ui/stdout-frame-writer.js +15 -0
- package/dist/ui/theme.d.ts +11 -0
- package/dist/ui/theme.js +2 -0
- package/dist/ui/transcript-text.js +72 -0
- package/dist/ui/use-startup-notices.d.ts +27 -1
- package/dist/ui/use-startup-notices.js +43 -11
- package/dist/ui/use-wheel-routing.d.ts +1 -1
- package/dist/ui/use-wheel-routing.js +8 -0
- package/package.json +4 -2
- package/dist/input/stdin-mouse-filter.d.ts +0 -42
- package/dist/input/stdin-mouse-filter.js +0 -153
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,259 @@ All notable changes to `@aragon-agent/cli` are documented here. Entries at
|
|
|
5
5
|
— those releases really were published under that name, so they are left as they
|
|
6
6
|
were written.
|
|
7
7
|
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **The composer understands pasting.** Until now it did not have the concept at
|
|
13
|
+
all: every byte the terminal delivered on stdin was a keystroke, and a
|
|
14
|
+
clipboard block is thousands of bytes arriving in an unpredictable number of
|
|
15
|
+
chunks. Three separate failures fell out of that one omission, and on Windows
|
|
16
|
+
you hit all three at once.
|
|
17
|
+
|
|
18
|
+
A carriage return that landed alone in a chunk **sent the half-finished
|
|
19
|
+
message** — a fifteen-line paste could arrive as a dozen separate messages,
|
|
20
|
+
interleaved with the agent's replies. A carriage return in the middle of a
|
|
21
|
+
chunk was inserted into the draft as a literal `\r`, which the terminal obeyed
|
|
22
|
+
by **overwriting the row it was drawn on**. And a paste that survived both grew
|
|
23
|
+
the composer to the height of the pasted text, pushing the transcript out of a
|
|
24
|
+
frame whose row accounting still believed the composer was three rows tall.
|
|
25
|
+
|
|
26
|
+
Pasting now works the way it reads:
|
|
27
|
+
|
|
28
|
+
- **A paste never submits.** Line breaks become buffer newlines, exactly one
|
|
29
|
+
per source line break, `CRLF` and lone `CR` alike.
|
|
30
|
+
- **A short paste appears verbatim.** At or below 6 lines and 400 characters it
|
|
31
|
+
is inserted as-is, indentation intact, and renders exactly like typed text.
|
|
32
|
+
- **A large paste collapses to a placeholder** — `[Pasted text #1 +218 lines]`
|
|
33
|
+
— which occupies one line, carries its own size in its label, deletes as a
|
|
34
|
+
single unit (one `Backspace`, and `Ctrl+W` / `Ctrl+U` / `Ctrl+K` cannot leave
|
|
35
|
+
half of one behind), and expands back to the full text the moment you send.
|
|
36
|
+
The model receives every byte; the composer never has to draw them.
|
|
37
|
+
- **No pasted byte is executed as a terminal control.** `\r`, `\x1b`, NUL, DEL
|
|
38
|
+
and the C1 range are stripped from the payload — never from your keystrokes,
|
|
39
|
+
so `Ctrl+A` and Escape are untouched.
|
|
40
|
+
- **The composer has a ceiling.** A draft of any length occupies at most 3 / 6 /
|
|
41
|
+
10 rows depending on terminal height, scrolls internally to keep the caret
|
|
42
|
+
visible, shows how many rows are hidden above and below, and reports its true
|
|
43
|
+
height to the layout budget. Four hundred presses of `Shift+Enter` were
|
|
44
|
+
already able to destroy the frame; they no longer are.
|
|
45
|
+
- **A submitted message cannot make the transcript unresponsive.** A user entry
|
|
46
|
+
renders at most 40 rows plus a `... +N more lines` tail. The full text is kept
|
|
47
|
+
and the exit transcript is uncapped.
|
|
48
|
+
|
|
49
|
+
On terminals that support it, detection is **exact**: aragon asks for bracketed
|
|
50
|
+
paste (`DECSET 2004`) in full-screen mode and reads the markers the terminal
|
|
51
|
+
wraps your paste in. Where that is unavailable — inline mode, an old Windows
|
|
52
|
+
console — a heuristic on chunk shape catches the same cases, and it needs no
|
|
53
|
+
cooperation from the terminal at all. Both feed one code path.
|
|
54
|
+
|
|
55
|
+
Turn it off with `--no-paste`, `ARAGON_PASTE=0`, or
|
|
56
|
+
`aragon config set paste false`; the input path is then byte-for-byte what
|
|
57
|
+
0.6.2 did.
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
61
|
+
- **A pasted API key is stored correctly again.** Ink broadcasts each stdin chunk
|
|
62
|
+
to every mounted input handler, so the settings screen, the question overlay
|
|
63
|
+
and the plan-review feedback field all see what the composer sees. Without
|
|
64
|
+
this, a ~100-character key pasted into Settings would have been stored wrapped
|
|
65
|
+
in invisible framing bytes, masked on screen by the password dots, and would
|
|
66
|
+
have failed to authenticate on every request afterwards with nothing anywhere
|
|
67
|
+
explaining why.
|
|
68
|
+
|
|
69
|
+
- **`--no-mouse` still writes no mouse sequence.** Paste support installs a
|
|
70
|
+
stdin filter, and `paste` defaults to on, so the filter now exists in sessions
|
|
71
|
+
that disabled the mouse. Whether the mouse is on is a separate question from
|
|
72
|
+
whether the stream is wrapped, and the four places that used to conflate them
|
|
73
|
+
now ask the right one: `aragon --no-mouse` writes no `?1000h`, no `?1006h` and
|
|
74
|
+
no `?1002h`, leaves your terminal's own click-drag selection alone, and reports
|
|
75
|
+
`/mouse` as off — while pasting still works.
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
|
|
79
|
+
- **Auto-compaction no longer reports compactions that did not happen.** A long
|
|
80
|
+
unattended run used to print a red `context not compacted #2: nothing_to_drop`
|
|
81
|
+
card into the transcript. The card was accurate; nobody had asked for it.
|
|
82
|
+
Auto-compaction evaluates itself at every turn boundary, and a checkpoint that
|
|
83
|
+
looks at the history and finds nothing worth dropping has changed nothing,
|
|
84
|
+
called nothing and spent nothing — a smoke alarm announcing "no fire" twice an
|
|
85
|
+
hour, in error colours, with a machine reason attached.
|
|
86
|
+
|
|
87
|
+
A compaction now announces itself **if and only if it commits to doing work**.
|
|
88
|
+
That is a position in the control flow, not a list of reason strings: everything
|
|
89
|
+
decided before the first spend is silent, and everything decided after it —
|
|
90
|
+
including every failure, the truncation fallback, an Esc, and a host fault — is
|
|
91
|
+
as loud as it ever was. A declined `pressure` checkpoint is now
|
|
92
|
+
indistinguishable from a turn on which the threshold was never crossed.
|
|
93
|
+
|
|
94
|
+
**`/compact` and overflow recovery are unchanged.** A compaction you asked for
|
|
95
|
+
is owed an answer, and a reactive compaction running after the provider has
|
|
96
|
+
already refused your request is the one moment the diagnosis matters most. Both
|
|
97
|
+
still report on every outcome.
|
|
98
|
+
|
|
99
|
+
**Quiet, not unrecorded.** Every attempt is still written to the diagnostic log
|
|
100
|
+
(its `compaction` line gains an `announced` field, so `announced: false` is one
|
|
101
|
+
grep), still charged to the anti-loop guards, and still counted by
|
|
102
|
+
`/compact status` — which now reads
|
|
103
|
+
`This session: 1 compaction (2 checkpoints declined), 94.2k tokens reclaimed`
|
|
104
|
+
when checkpoints declined, and is byte-identical to before when none did. If
|
|
105
|
+
declines keep happening, the self-disable notice still says so out loud, once,
|
|
106
|
+
naming the cause and the remedies. Card numbers are also contiguous again: `#N`
|
|
107
|
+
counts compactions that ran, not checkpoints that fired.
|
|
108
|
+
|
|
109
|
+
**Behaviour change for wrapper scripts.** A declined `pressure` compaction no
|
|
110
|
+
longer emits a `{ type: 'compaction', subtype: 'start' | 'end' }` pair on the
|
|
111
|
+
`--output-format json` stream, and no longer prints `[compaction] skipped:` on
|
|
112
|
+
`-p` stderr. The pairs stay balanced, so only consumers counting *attempts* are
|
|
113
|
+
affected; the diagnostic log reports those more accurately.
|
|
114
|
+
|
|
115
|
+
### Added
|
|
116
|
+
|
|
117
|
+
- **Context compaction, hardened — the trigger now counts the whole history, the
|
|
118
|
+
recent turns can no longer wedge a run, sub-agents get the same protection, and
|
|
119
|
+
a compaction is no longer irreversible.**
|
|
120
|
+
|
|
121
|
+
**The trigger was systematically late.** It fired on the provider's reported
|
|
122
|
+
usage for the PREVIOUS request, read at a checkpoint that runs AFTER the current
|
|
123
|
+
turn's tool results were appended — and tool results are the largest single
|
|
124
|
+
increment in this loop (100 KB per call, several per turn, ~25 k tokens each).
|
|
125
|
+
A session reading 88 % could be sending 110 %. Occupancy is now the measured
|
|
126
|
+
base PLUS an estimate of everything appended since that measurement, and the
|
|
127
|
+
status gauge reads the same number the trigger does, on every turn — including
|
|
128
|
+
the turns where a guard declines to compact, which is exactly when the number
|
|
129
|
+
matters most.
|
|
130
|
+
|
|
131
|
+
**The recent turns can no longer wedge a run.** Every previous rung of the
|
|
132
|
+
ladder operated on the head of the conversation. When the RETAINED tail was what
|
|
133
|
+
did not fit, each rung reported success or "nothing to drop" while the history
|
|
134
|
+
stayed un-sendable and the run died. Oversized `tool_result` bodies inside the
|
|
135
|
+
retained turns are now clipped, oldest first, only when the alternative is a
|
|
136
|
+
request the provider cannot accept. Nothing is removed — no message, no
|
|
137
|
+
tool-call id, no role — so a valid history stays valid. Every clip is announced
|
|
138
|
+
in the text the model reads, at the exact place the data went, and on the card,
|
|
139
|
+
in `/compact status`, on the JSON stream and in the archive.
|
|
140
|
+
|
|
141
|
+
**Sub-agents compact their own history** (`compaction.subagents`, default
|
|
142
|
+
`true`). A `task` child is bounded by 24 turns and fifteen minutes, and when one
|
|
143
|
+
overflowed its entire history was discarded and the dispatch reached the lead as
|
|
144
|
+
one partial sentence. Children run under tighter bounds than the lead: two
|
|
145
|
+
retained turns, at most two compactions, the fast tier preferred, and failure
|
|
146
|
+
forced to truncate because nobody is watching a background worker. No transcript
|
|
147
|
+
card — the lead's transcript describes the lead's context. Set
|
|
148
|
+
`compaction.subagents: false` to restore the previous behaviour exactly.
|
|
149
|
+
|
|
150
|
+
**A compaction is no longer irreversible** (`compaction.archive`, default
|
|
151
|
+
`true`). The dropped messages are written verbatim to `~/.aragon/compaction/`
|
|
152
|
+
before the splice is adopted. `/compact history` lists this run's archives,
|
|
153
|
+
`/compact show <n>` prints one's metadata and summary — never message bodies.
|
|
154
|
+
The directory is shared by every `aragon` on the machine, so files carry a
|
|
155
|
+
per-process run id and retention is two-tier: 20 files per run by count, plus a
|
|
156
|
+
seven-day sweep across all runs, so one session can never prune a live
|
|
157
|
+
neighbour's work. Writing is best-effort: a failure is logged and never affects
|
|
158
|
+
the compaction. This is deliberately **not** undo — restoring an over-full
|
|
159
|
+
history restores the condition that triggered the compaction.
|
|
160
|
+
|
|
161
|
+
**The long moment is legible.** The live card counts elapsed seconds and says
|
|
162
|
+
`esc to cancel`, which `AgentController.abort()` has always made true and no
|
|
163
|
+
surface has ever stated. A compaction that could only clip says so and names no
|
|
164
|
+
model, because none was called.
|
|
165
|
+
|
|
166
|
+
Two new config keys (`compaction.subagents`, `compaction.archive`), two new
|
|
167
|
+
environment variables (`ARAGON_COMPACTION_SUBAGENTS`,
|
|
168
|
+
`ARAGON_COMPACTION_ARCHIVE`), two new `/compact` verbs (`history`, `show <n>`),
|
|
169
|
+
and two new settings-screen rows. No flags were added.
|
|
170
|
+
|
|
171
|
+
- **Context compaction — a long run no longer dies when the window fills, and it
|
|
172
|
+
is ON by default.** A session's conversation only grows: nothing anywhere
|
|
173
|
+
removed a message, so a 40-turn tool-heavy run had exactly one ending available
|
|
174
|
+
to it once the context window filled — an HTTP 400 and a banner reading
|
|
175
|
+
*"Context length exceeded — start a new conversation with /reset."* The
|
|
176
|
+
product's answer to running out of context was "throw away everything you were
|
|
177
|
+
doing."
|
|
178
|
+
|
|
179
|
+
Now, at **90 %** occupancy, the run pauses at a turn boundary, hands the older
|
|
180
|
+
part of the history to a summarizer, and swaps it for a structured record. Your
|
|
181
|
+
original task stays **verbatim**, the most recent turns stay **verbatim**, and
|
|
182
|
+
the run continues in the same loop with the same tools, the same todo list and
|
|
183
|
+
the same working directory.
|
|
184
|
+
|
|
185
|
+
**This changes behaviour for existing users, in the direction of not dying.**
|
|
186
|
+
`--no-compaction`, or `compaction.enabled: false`, restores the old behaviour
|
|
187
|
+
exactly: no manager is constructed, nothing is subscribed, no registry is
|
|
188
|
+
allocated, and a full window ends the run as it did before. Both flag forms are
|
|
189
|
+
declared, so a stored `false` survives a run that passes no flags.
|
|
190
|
+
|
|
191
|
+
Three ways it fires. **Proactively** on measured occupancy — the case that
|
|
192
|
+
happens almost every time. **Reactively** when the provider returns
|
|
193
|
+
`context_overflow` anyway, because the model is not in the static window table
|
|
194
|
+
or you are pointed at a proxy in front of a smaller one: one compaction, one
|
|
195
|
+
re-send, run continues. And **manually**, via `/compact`, which runs
|
|
196
|
+
immediately when idle and queues to the next turn boundary when running.
|
|
197
|
+
|
|
198
|
+
The trigger has two terms. 90 % of a 200 k window leaves 20 k, which is plenty;
|
|
199
|
+
90 % of a 32 k window leaves 3.2 k, which is less than a single `max_tokens` of
|
|
200
|
+
8192 — the request is already impossible. So compaction also fires whenever the
|
|
201
|
+
remaining headroom drops below one full response.
|
|
202
|
+
|
|
203
|
+
**The default summarizer is your own model, and that costs real money.**
|
|
204
|
+
`compaction.useFastTier` is `true`, but it is a *preference*: the fast tier is
|
|
205
|
+
off unless you configured it, so out of the box the first compaction is a
|
|
206
|
+
~30 k-token call on the session's own model. It happens at most 5 times per
|
|
207
|
+
run, the alternative is losing the run entirely, and the spend is visible — in
|
|
208
|
+
the session total, priced with the summarizer's own table, and reported as
|
|
209
|
+
`pricing unknown` rather than `$0.00` when that table has never seen the model.
|
|
210
|
+
Configure the fast tier to make it cheap.
|
|
211
|
+
|
|
212
|
+
Summarization fails sometimes. The ladder is one retry (on your **main** model
|
|
213
|
+
if the first attempt used the fast tier), then a **truncation** that says so on
|
|
214
|
+
the card, on the JSON event stream, and inside the block the model itself
|
|
215
|
+
reads. `compaction.onFailure: "stop"` makes the other trade.
|
|
216
|
+
|
|
217
|
+
Four guards stop it looping on your money: never two on consecutive turns,
|
|
218
|
+
never more than 5 per run, a progress requirement, and a self-disable after two
|
|
219
|
+
no-progress attempts with a notice naming the cause and the fix. The guards are
|
|
220
|
+
**trigger-aware** — the reactive path stays armed even after a self-disable,
|
|
221
|
+
because a compaction answering a request the provider has already refused is
|
|
222
|
+
the difference between a live run and a dead one.
|
|
223
|
+
|
|
224
|
+
Three UI surfaces: `Compacting context…` on the activity row while it runs, a
|
|
225
|
+
`compacting` chip plus threshold-aligned gauge colours as state, and a
|
|
226
|
+
transcript card with the before/after counts, the summarizer, the duration and
|
|
227
|
+
an expandable summary as the record. The gauge falls **immediately** rather
|
|
228
|
+
than waiting for the next turn. `/compact status` is the guaranteed surface at
|
|
229
|
+
any width.
|
|
230
|
+
|
|
231
|
+
New: `compaction` config section (6 keys), `--compaction` / `--no-compaction` /
|
|
232
|
+
`--compaction-threshold`, `ARAGON_COMPACTION*` (3 vars), `/compact` (6 forms),
|
|
233
|
+
three settings-screen rows, a `compaction` event on the `aragon exec` JSON
|
|
234
|
+
stream (`EXEC_SCHEMA_VERSION` **unchanged** — adding an event type never bumps
|
|
235
|
+
it), and two stderr lines under `-p`.
|
|
236
|
+
|
|
237
|
+
### Changed
|
|
238
|
+
|
|
239
|
+
- **The context gauge now counts cache tokens**, through the same
|
|
240
|
+
`occupiedTokens` the compaction trigger reads. Anthropic reports `input_tokens`
|
|
241
|
+
*excluding* cached tokens and puts them in two separate fields, so the old
|
|
242
|
+
`inputTokens + outputTokens` silently under-reported occupancy for anyone
|
|
243
|
+
behind a caching gateway. That was already a defect in the number on the status
|
|
244
|
+
bar; it becomes a much worse one the moment a trigger fires on a different
|
|
245
|
+
number from the one you are watching.
|
|
246
|
+
|
|
247
|
+
- **`context_overflow` now names `/compact` alongside `/reset`.** That remedy
|
|
248
|
+
list was complete until this release, because throwing the conversation away
|
|
249
|
+
really was the only exit.
|
|
250
|
+
|
|
251
|
+
### Known limitation
|
|
252
|
+
|
|
253
|
+
- **A summarizer that is 90 % faithful will, eventually, drop something the run
|
|
254
|
+
needed,** and no amount of prompt engineering closes that. The design bounds it
|
|
255
|
+
— verbatim task, verbatim recent turns, a block that tells the model the record
|
|
256
|
+
is partial, and three surfaces that make it visible so a human can step in —
|
|
257
|
+
but it does not eliminate it. That is inherent to compaction as a technique, it
|
|
258
|
+
is the same trade Claude Code and Codex make, and it is preferable by a wide
|
|
259
|
+
margin to the previous behaviour, which was to lose the entire run.
|
|
260
|
+
|
|
8
261
|
## 0.6.0
|
|
9
262
|
|
|
10
263
|
### Added
|
|
@@ -84,6 +337,74 @@ were written.
|
|
|
84
337
|
|
|
85
338
|
## Unreleased
|
|
86
339
|
|
|
340
|
+
### Added
|
|
341
|
+
|
|
342
|
+
- **Drag the mouse to select text, and release to copy it.** Full-screen mode
|
|
343
|
+
takes the alternate screen, turns on mouse reporting so the wheel can scroll a
|
|
344
|
+
transcript the terminal no longer knows how to scroll, and draws every row
|
|
345
|
+
itself. Each of those is right on its own; together they took your terminal's
|
|
346
|
+
own drag-to-select away and put nothing in its place. The only thing shipped
|
|
347
|
+
in its place was a one-line notice naming a bypass key that is Shift on some
|
|
348
|
+
emulators, Fn on others and a preference elsewhere — a workaround, told once,
|
|
349
|
+
in a line that scrolls away.
|
|
350
|
+
|
|
351
|
+
Press the left button and drag: the cells you drag across are highlighted as
|
|
352
|
+
you go, and releasing copies exactly them. The copy goes out over **OSC 52**
|
|
353
|
+
first, so it reaches the clipboard of the machine you are *sitting at* rather
|
|
354
|
+
than the one you are ssh'd into, with the platform clipboard binary attempted
|
|
355
|
+
alongside it for terminals that ignore the sequence. Neither mechanism is
|
|
356
|
+
detectable, so the toast names what was sent rather than claiming a success it
|
|
357
|
+
cannot verify. `/copy` now goes through the same path and gained ssh support on
|
|
358
|
+
the way.
|
|
359
|
+
|
|
360
|
+
The highlight is painted in the frame pipeline rather than in React, so a drag
|
|
361
|
+
costs one to three re-addressed rows instead of a re-render of the whole tree,
|
|
362
|
+
and the text that is copied is read from the same mirrored rows the highlight
|
|
363
|
+
was painted over — what you see is what you get by construction, not by a
|
|
364
|
+
staleness check that can be wrong.
|
|
365
|
+
|
|
366
|
+
Two switches, both reversible without a restart: `/mouse off` hands the mouse
|
|
367
|
+
back to your terminal for the session (and says plainly that the wheel goes
|
|
368
|
+
inert while it is off), `/mouse on` takes it back, and
|
|
369
|
+
`aragon config set mouseSelect false` keeps wheel scrolling while leaving
|
|
370
|
+
drag-select off — which also stops the CLI asking the terminal for motion
|
|
371
|
+
reports at all, so that session puts exactly the bytes on the wire that it did
|
|
372
|
+
before this release. `--no-mouse` remains the switch that captures nothing.
|
|
373
|
+
|
|
374
|
+
### Changed
|
|
375
|
+
|
|
376
|
+
- **Scrolling up now actually stops the transcript.** The viewport followed the
|
|
377
|
+
newest output by holding a *fixed distance from the bottom*, so scrolling up
|
|
378
|
+
during a run did not pause anything: twelve new rows of output moved the
|
|
379
|
+
window twelve rows down, and whatever you had scrolled up to read slid off the
|
|
380
|
+
top while you were reading it. The faster the agent talked, the faster your
|
|
381
|
+
reading position ran away.
|
|
382
|
+
|
|
383
|
+
While you are scrolled up, the transcript is now anchored to the **content**:
|
|
384
|
+
new output accumulates below the window instead of dragging the window along
|
|
385
|
+
with it, and the rows on screen hold still. After five seconds with no
|
|
386
|
+
scrolling the viewport returns to the newest line by itself — but only if
|
|
387
|
+
something actually arrived while you were paused, so reading a *finished*
|
|
388
|
+
transcript is never interrupted by a jump to a bottom that has not moved.
|
|
389
|
+
Every gesture restarts the countdown, a selection drag suspends it, and
|
|
390
|
+
`aragon config set scrollResumeMs 0` turns the return off entirely
|
|
391
|
+
(`ARAGON_SCROLL_RESUME_MS` sets it too).
|
|
392
|
+
|
|
393
|
+
The number the hint shows means something sharper as a result: it is now
|
|
394
|
+
literally "rows of newer output below your reading position", which is what
|
|
395
|
+
`PgDn` traverses and what the status bar's `↑N` has always shown.
|
|
396
|
+
|
|
397
|
+
- **The "N new lines · PgDn" hint moved inside the input box.** It used to be
|
|
398
|
+
rendered as the viewport's own last row, which spent a line of your transcript
|
|
399
|
+
on chrome at exactly the moment the transcript was longest — and, because the
|
|
400
|
+
hint's presence shrank the viewport, it fed back into the very number it was
|
|
401
|
+
displaying. It is now a right-aligned chip on the composer's input row, inside
|
|
402
|
+
the border, where it costs no rows at all. The chip sits in a fixed-width cell
|
|
403
|
+
so the number gaining a digit cannot re-wrap a draft, it never truncates (the
|
|
404
|
+
draft wraps first), and unlike the teaching row below the box it neither fades
|
|
405
|
+
with experience nor disappears on a short terminal: how far behind you are is
|
|
406
|
+
state, not a tutorial.
|
|
407
|
+
|
|
87
408
|
### Fixed
|
|
88
409
|
|
|
89
410
|
- **The working spinner no longer disappears when an ack takes its row.** Steer a
|