@aragon-agent/cli 0.6.25 → 0.6.26
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 +89 -0
- package/README.md +165 -13
- package/dist/agent/reducer.d.ts +22 -0
- package/dist/agent/reducer.js +4 -1
- package/dist/cli.js +214 -2
- package/dist/commands/branch-command.d.ts +61 -0
- package/dist/commands/branch-command.js +117 -0
- package/dist/commands/builtins.js +48 -6
- package/dist/commands/registry.d.ts +28 -0
- package/dist/commands/session-command.d.ts +54 -0
- package/dist/commands/session-command.js +109 -0
- package/dist/config/load.d.ts +15 -0
- package/dist/exec/index.js +10 -1
- package/dist/logging/logger.d.ts +1 -1
- package/dist/proc/terminal-plan.d.ts +155 -0
- package/dist/proc/terminal-plan.js +360 -0
- package/dist/session/branch-invocation.d.ts +83 -0
- package/dist/session/branch-invocation.js +109 -0
- package/dist/session/branch-launch.d.ts +70 -0
- package/dist/session/branch-launch.js +248 -0
- package/dist/session/checkpoint.d.ts +257 -0
- package/dist/session/checkpoint.js +512 -0
- package/dist/session/cli-commands.d.ts +2 -0
- package/dist/session/cli-commands.js +36 -5
- package/dist/session/identity.d.ts +72 -0
- package/dist/session/identity.js +148 -0
- package/dist/session/limits.d.ts +66 -0
- package/dist/session/limits.js +66 -0
- package/dist/session/persist.d.ts +30 -5
- package/dist/session/startup-session.d.ts +107 -0
- package/dist/session/startup-session.js +315 -0
- package/dist/session/store.d.ts +60 -1
- package/dist/session/store.js +95 -6
- package/dist/ui/App.d.ts +54 -2
- package/dist/ui/App.js +115 -21
- package/dist/ui/Header.js +8 -16
- package/dist/ui/StatusBar.d.ts +8 -0
- package/dist/ui/StatusBar.js +12 -3
- package/dist/ui/layout/header-hints.d.ts +68 -0
- package/dist/ui/layout/header-hints.js +138 -0
- package/dist/ui/layout/session-chip.d.ts +52 -0
- package/dist/ui/layout/session-chip.js +64 -0
- package/dist/ui/layout/status-layout.d.ts +10 -0
- package/dist/ui/layout/status-layout.js +8 -1
- package/dist/ui/overlays/HelpOverlay.js +9 -3
- package/dist/ui/session-bridge.d.ts +26 -0
- package/dist/ui/session-bridge.js +32 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,46 @@ were written.
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
|
+
- **`Ctrl+L` branches this session into a new terminal - and `Ctrl+R` now
|
|
12
|
+
redraws (KEY BINDING CHANGE).** One keystroke opens a PowerShell (Windows) or
|
|
13
|
+
bash (macOS/Linux) window in the session's current `/cwd`, running
|
|
14
|
+
`aragon --resume <id>` there: the child derives its own id and only ever writes
|
|
15
|
+
its own file, so the TUI you branched from keeps running untouched. The session
|
|
16
|
+
is force-flushed to disk BEFORE anything is spawned, because the child reads
|
|
17
|
+
that file first and the normal checkpoint is debounced. Works mid-run too - the
|
|
18
|
+
child inherits the last settled turn. Platforms: a new Windows Terminal tab
|
|
19
|
+
(`wt -d <cwd> ... --`), a new console window (`cmd /c start`), a Terminal.app
|
|
20
|
+
window via `osascript`, or the first available Linux emulator; each rung carries
|
|
21
|
+
the working directory itself, because `--resume` does not restore one. No
|
|
22
|
+
terminal (SSH, container) prints a pasteable `aragon --resume <id>` instead of
|
|
23
|
+
failing silently. `ARAGON_BRANCH_COMMAND` / `ARAGON_BRANCH_SHELL` override what
|
|
24
|
+
runs and which shell; presses are throttled to one window per two seconds and a
|
|
25
|
+
failed attempt never starts the cooldown. New `/branch` is the same code path.
|
|
26
|
+
The header (top right) now shows `^L branch` next to `^I Index` and `^G more`,
|
|
27
|
+
spending a fixed cell budget: `^I` therefore appears from 52 columns
|
|
28
|
+
(collapsed) / 62 columns (expanded) instead of 72, and on a very narrow terminal
|
|
29
|
+
the branch hint degrades to the bare `^L` before it is dropped.
|
|
30
|
+
**Breaking:** the redraw previously bound to `Ctrl+L` moved to `Ctrl+R` - same
|
|
31
|
+
behaviour, same overlay guard (the settings screen keeps its own `Ctrl+R`).
|
|
32
|
+
|
|
33
|
+
- **A TUI session now has an id, and another terminal can continue it.** Every
|
|
34
|
+
interactive session is written to `~/.aragon-agent/sessions/<id>.json` as it
|
|
35
|
+
runs and shows that id at the right end of the status bar (`id a4k2m9`, or
|
|
36
|
+
`a4k2m9` on a narrow terminal - the id itself is never truncated). Checkpoints
|
|
37
|
+
are written after the first frame, after every settled turn (debounced), on
|
|
38
|
+
`/session pin`, and once on exit; each one is an atomic replace, because a
|
|
39
|
+
second terminal may be reading. `aragon --resume <id|path>` continues a saved
|
|
40
|
+
session under a NEW id and never writes the file it came from, so branching
|
|
41
|
+
while the original TUI keeps running is safe - including
|
|
42
|
+
`aragon exec --resume <tui-id>`, which now writes a session of its own instead
|
|
43
|
+
of overwriting yours. `aragon --save <id>` names this run's id and pins it
|
|
44
|
+
against `sessions prune`. New `/session [copy|pin]` reports the id, the file and
|
|
45
|
+
the branch parent, copies the resume command through the same clipboard door as
|
|
46
|
+
`/copy` (OSC 52 included), and pins the file. A checkpoint taken mid-tool is
|
|
47
|
+
repaired on the saved copy only, so resuming it cannot produce an illegal
|
|
48
|
+
history, and a tool card that was still running is settled so nothing spins
|
|
49
|
+
after a resume. `aragon -p` writes one checkpoint at exit: context only, no
|
|
50
|
+
transcript, because nothing was displayed.
|
|
11
51
|
|
|
12
52
|
- **A model profile can be verified where it is written.** The profile editor
|
|
13
53
|
gains two action rows: **Test connection** (`Ctrl+R`) and **Discover models**
|
|
@@ -23,8 +63,57 @@ were written.
|
|
|
23
63
|
describe a model, endpoint or key the user has since edited. The progress line
|
|
24
64
|
is static text: no new animated site, so `single-spinner` still holds.
|
|
25
65
|
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- **`aragon sessions list` gained an `origin` column** and shows TUI checkpoints,
|
|
69
|
+
which are managed files now. `sessions prune` defaults to `--origin exec`, so it
|
|
70
|
+
behaves exactly as before for every file that existed before this release; the
|
|
71
|
+
new `--origin tui|all` selects the other writer. `prune` never deletes a pinned
|
|
72
|
+
session or one whose owner process is still alive, and `--all` now means only
|
|
73
|
+
"also consider files with no session metadata" - it can no longer reach a TUI
|
|
74
|
+
checkpoint. `/resume` inside the TUI moves the session to a new id and restarts
|
|
75
|
+
the spend counter, because a new id's file must not bill the previous
|
|
76
|
+
conversation.
|
|
77
|
+
|
|
26
78
|
### Fixed
|
|
27
79
|
|
|
80
|
+
- **A conversation saved mid-tool could be resumed into an illegal history.**
|
|
81
|
+
A `tool_call` with no matching `tool_result` makes the next request fail. The
|
|
82
|
+
checkpoint writer closes every dangling call on the copy it writes and re-checks
|
|
83
|
+
sendability before replacing the file; a history it cannot make sendable is not
|
|
84
|
+
written at all, so the previous good checkpoint survives.
|
|
85
|
+
- **A checkpoint could carry a tool card that never stopped spinning.** A card
|
|
86
|
+
saved while its tool was running kept `ToolCard` animated and kept the
|
|
87
|
+
transcript's settled boundary from ever passing it, which re-rendered the tail
|
|
88
|
+
on every frame for the rest of the resumed session. Cards are now settled on the
|
|
89
|
+
saved copy only, which leaves `/save` (an explicit export you are watching) and
|
|
90
|
+
its documented behaviour untouched.
|
|
91
|
+
- **`aragon exec --resume <tui-id>` overwrote the session it resumed.** The
|
|
92
|
+
write-back id preferred the file's own metadata, so exec took the TUI's id and
|
|
93
|
+
replaced the checkpoint - silent, unrecoverable loss of the conversation still
|
|
94
|
+
running in the other terminal. A TUI file now always yields a fresh id, and the
|
|
95
|
+
same rule covers `--session-id`, which used to return the typed id verbatim.
|
|
96
|
+
- **`sessions prune --origin tui --yes` could delete a running session's
|
|
97
|
+
checkpoint.** The `live` marker was written by the TUI but the process lock it
|
|
98
|
+
is checked against was only ever taken by `exec`, so the liveness guard answered
|
|
99
|
+
"nobody owns this" for exactly the files it was written for. The TUI checkpoint
|
|
100
|
+
writer now holds the session lock for as long as it owns the file, releases it
|
|
101
|
+
on exit, and moves it when `/resume` rotates the id.
|
|
102
|
+
- **`aragon --save <id>` said "already exists" for an id that does not exist.**
|
|
103
|
+
A session directory that cannot be written (read-only home, full disk) was
|
|
104
|
+
reported as a name collision, which sends the user to `--resume <id>` and then
|
|
105
|
+
to "no such session". It now names the directory instead.
|
|
106
|
+
- **A hand-written `/save` file resumed as if it were a branch of itself.**
|
|
107
|
+
`--resume ./notes.json` recorded `notes` as `meta.branchOf` and announced it as
|
|
108
|
+
the parent session, though it is not a session id. Lineage is now recorded only
|
|
109
|
+
for ids this CLI minted, and a collision while deriving a branch id re-mints the
|
|
110
|
+
suffix instead of dropping the branch shape.
|
|
111
|
+
- **`/session` answered `pinned no` right after `/session pin`.** The file was
|
|
112
|
+
marked and the report was not. The identity is now updated with the pin.
|
|
113
|
+
- **An id rotation could write one turn into the old id's file.** For the window
|
|
114
|
+
between `/resume` claiming a new id and the next render, the writer still aimed
|
|
115
|
+
at the previous file while recording the new parent. The rotation now republishes
|
|
116
|
+
the writer's id in the same step.
|
|
28
117
|
- **`/clear` did not clear the context.** It reset the visible transcript and the
|
|
29
118
|
todo panel and left `agent.state.messages` - the history that is actually sent,
|
|
30
119
|
billed, measured by `/context` and compacted - completely untouched. A long
|
package/README.md
CHANGED
|
@@ -197,7 +197,7 @@ supplying it is frequently the least trusted input in the pipeline.
|
|
|
197
197
|
aragon sessions list [--json] [-n 20] [--all]
|
|
198
198
|
aragon sessions show <id> [--json]
|
|
199
199
|
aragon sessions rm <id> --yes
|
|
200
|
-
aragon sessions prune [--older-than 7] [--dry-run] [--all] --yes
|
|
200
|
+
aragon sessions prune [--older-than 7] [--dry-run] [--all] [--origin exec|tui|all] --yes
|
|
201
201
|
aragon sessions path
|
|
202
202
|
```
|
|
203
203
|
|
|
@@ -312,19 +312,25 @@ section is the one that would be misled by their omission.
|
|
|
312
312
|
**On Windows only Ctrl-C does** — Node does not deliver the other two to
|
|
313
313
|
listeners, so `taskkill` ends the process outright. Resolve on process exit as
|
|
314
314
|
well as on `result`, or a killed run hangs your parent process.
|
|
315
|
-
3. **
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
315
|
+
3. **Resuming carries the model's full context, and only the scrollback that
|
|
316
|
+
was actually recorded.** `aragon --resume <id>` continues any saved session
|
|
317
|
+
— a TUI checkpoint, a TUI `/save` export, an `exec` session — under a NEW id,
|
|
318
|
+
with the whole conversation and no transcript replay for turns that ran
|
|
319
|
+
headlessly (`aragon -p`). A TUI checkpoint replays its screen faithfully.
|
|
320
|
+
4. **`aragon sessions prune` never deletes what you are still using.** It only
|
|
321
|
+
touches sessions this CLI wrote (files with a session metadata block), and it
|
|
322
|
+
defaults to `--origin exec`, so a TUI checkpoint is out of scope unless you
|
|
323
|
+
ask for it with `--origin tui`. `--all` widens "which rows exist" to
|
|
324
|
+
hand-written `/save` files and never reaches a TUI checkpoint; `pinned`
|
|
325
|
+
sessions and files whose owner process is still alive are never deleted.
|
|
326
|
+
`sessions show` and `sessions rm` accept any id, because you named it.
|
|
323
327
|
|
|
324
328
|
## Usage
|
|
325
329
|
|
|
326
330
|
```
|
|
327
331
|
aragon [prompt] Start the interactive TUI (or one-shot with -p / piped stdin)
|
|
332
|
+
aragon --resume <id|path> Continue a saved session under a NEW id (TUI or -p)
|
|
333
|
+
aragon --save <id> Name this session's id and pin it against `sessions prune`
|
|
328
334
|
aragon -p, --print [prompt] Headless: stream the answer to stdout, then exit
|
|
329
335
|
aragon exec [prompt] Machine-facing run: JSON events, sessions, permissions, budgets
|
|
330
336
|
aragon sessions <sub> [id] Manage exec sessions: list | show | rm | prune | path
|
|
@@ -397,6 +403,76 @@ Exit codes: `0` success · `1` agent/runtime error · `2` config/usage error ·
|
|
|
397
403
|
`3` stopped by a caller-set budget (`aragon exec` only) · `128 + signo` when a
|
|
398
404
|
signal ends the run (`130` SIGINT, `143` SIGTERM, `129` SIGHUP).
|
|
399
405
|
|
|
406
|
+
## Session identity, resume and branching
|
|
407
|
+
|
|
408
|
+
Every TUI session has a short id - six characters from an alphabet that omits
|
|
409
|
+
`0 o 1 l i`, so it can be read off a screen without a transcription mistake - and
|
|
410
|
+
that id is shown at the right end of the status bar. It is also written to
|
|
411
|
+
`~/.aragon-agent/sessions/<id>.json` as the conversation proceeds, which is what
|
|
412
|
+
lets a second terminal continue the same conversation.
|
|
413
|
+
|
|
414
|
+
**The chip.** `id a4k2m9` when there is room (72 columns and up), `a4k2m9` below
|
|
415
|
+
that, and nothing at all when even the id would crowd the status fields. An id is
|
|
416
|
+
never truncated: half an id is a `--resume` command that cannot work, which is
|
|
417
|
+
worse than no id, and `/session` reports the full id at any width. In the one
|
|
418
|
+
layout where the status row itself is not drawn (a terminal too short for a single
|
|
419
|
+
status line), the chip is absent by design and `/session` is the way to read it.
|
|
420
|
+
|
|
421
|
+
**When it is written.** After the first frame (so the id on screen is resumable
|
|
422
|
+
before the first message), after every settled turn (debounced, so a run that
|
|
423
|
+
restarts itself does not write twice), on `/session pin`, and once on the way out.
|
|
424
|
+
`aragon -p` has no screen and no turn events, so it writes exactly once, at exit.
|
|
425
|
+
Every write replaces the file atomically - this is the first session file in this
|
|
426
|
+
CLI that a reader may be looking at while it is rewritten.
|
|
427
|
+
|
|
428
|
+
**What a checkpoint contains.** The full conversation, the todo list, the model
|
|
429
|
+
and the transcript, plus a `meta` block naming the writer. A turn interrupted
|
|
430
|
+
mid-tool is repaired ON THE COPY: the dangling `tool_call` gets an `isError`
|
|
431
|
+
`tool_result` so the next request is legal, and any tool card still running is
|
|
432
|
+
settled, so a resumed session has nothing left spinning. The live conversation is
|
|
433
|
+
never edited to achieve this.
|
|
434
|
+
|
|
435
|
+
**Branching.** `aragon --resume <id|path>` reads the named session and continues
|
|
436
|
+
it under a **new** id (`a4k2m9-x7f2`, or a fresh id when the file was a
|
|
437
|
+
hand-written `/save` export). The session it came from is not written again by
|
|
438
|
+
this process - not its contents, not its `savedAt` - and `--continue` never points
|
|
439
|
+
at it. That is what makes it safe to branch while the original TUI keeps running.
|
|
440
|
+
(`aragon exec --resume <id>` follows the same rule: it reads your session and
|
|
441
|
+
writes one of its own. `--continue` then names the newest **exec** session, which
|
|
442
|
+
is the new one - it never names the TUI session it read.)
|
|
443
|
+
|
|
444
|
+
Three entry points, three different behaviours, on purpose:
|
|
445
|
+
|
|
446
|
+
| Command | Reads | Writes |
|
|
447
|
+
| --- | --- | --- |
|
|
448
|
+
| `aragon --resume <id\|path>` | the session you name | a NEW branch session; the parent is never touched |
|
|
449
|
+
| `/resume [file]` (inside the TUI) | the file you name | this process moves to a NEW id, and the spend counter restarts |
|
|
450
|
+
| `aragon exec --resume <id\|path>` | the session you name | a new exec session of its own - including when the session you named was written by the TUI |
|
|
451
|
+
|
|
452
|
+
**Naming a session.** `aragon --save <id>` names this run's persistent id and pins
|
|
453
|
+
it: `sessions prune` will never delete it. The value must be an id, not a path
|
|
454
|
+
(`--save ./notes.json` exits 2 and says so); use `/save` inside the TUI to export
|
|
455
|
+
to a file. `aragon --save <id>` refuses an id that already exists, and refuses the
|
|
456
|
+
id you are resuming - either would mean writing over a session you still have.
|
|
457
|
+
|
|
458
|
+
**`/session`.** Bare `/session` reports the id, the file it is written to, the
|
|
459
|
+
branch parent (if any), whether it is pinned, and the two commands worth pasting.
|
|
460
|
+
`/session copy` puts `aragon --resume <id>` on the clipboard through the same door
|
|
461
|
+
`/copy` uses (OSC 52 included, so it works over SSH). `/session pin` writes once
|
|
462
|
+
and marks the file as never-prunable.
|
|
463
|
+
|
|
464
|
+
**Why there is no switch.** Sessions are recorded by default, exactly as
|
|
465
|
+
`aragon exec` already wrote them by default, and there is deliberately no
|
|
466
|
+
"show the id but do not save it" mode: it would leave an id you can copy and
|
|
467
|
+
cannot use. `sessions rm <id> --yes` is the explicit way to delete one, and
|
|
468
|
+
nothing is ever deleted automatically.
|
|
469
|
+
|
|
470
|
+
**Headless checkpoints carry context, not scrollback.** A session continued with
|
|
471
|
+
`aragon -p` records the conversation but no transcript, because nothing was ever
|
|
472
|
+
displayed. `aragon --resume` of such a file inherits the full context and shows an
|
|
473
|
+
empty screen until the next turn - the alternative, inventing entries, would put
|
|
474
|
+
a conversation the user never saw onto their screen.
|
|
475
|
+
|
|
400
476
|
## Slash commands (interactive)
|
|
401
477
|
|
|
402
478
|
| Command | Action |
|
|
@@ -410,8 +486,9 @@ signal ends the run (`130` SIGINT, `143` SIGTERM, `129` SIGHUP).
|
|
|
410
486
|
| `/clear` | Start a new conversation: interrupt the run, archive the old session, clear the context, transcript, queues and todo panel. `/clear screen` only clears the screen |
|
|
411
487
|
| `/reset` | Alias of `/clear` - one implementation, so the two cannot drift apart |
|
|
412
488
|
| `/cwd [dir]` | Show / change the tool working directory |
|
|
413
|
-
| `/save [file]` |
|
|
414
|
-
| `/resume [file]` | Load a saved session |
|
|
489
|
+
| `/save [file]` | Export the session to JSON - a file you keep, unchanged by this feature |
|
|
490
|
+
| `/resume [file]` | Load a saved session. This session moves to a NEW id, and the spend counter restarts |
|
|
491
|
+
| `/session [copy\|pin]` | Report this session's id, file and branch parent; `copy` puts `aragon --resume <id>` on the clipboard; `pin` makes `sessions prune` skip the file forever |
|
|
415
492
|
| `/plan [on\|off\|status]` | Toggle plan mode - the keyboard-free equivalent of `Shift+Tab` |
|
|
416
493
|
| `/team [on\|off\|max <n>\|overseer on\|off\|model [main\|fast\|<profile-name>]]` | Team subagents: status and the live roster, the on/off switch, the fan-out width, the dispatch supervisor |
|
|
417
494
|
| `/todo [on\|off\|panel on\|off\|follow <mode>\|clear\|continue]` | Todo planning: status, the on/off switch, the rail, follow-through, and picking an unfinished plan back up |
|
|
@@ -449,7 +526,8 @@ completes, `Up` / `Down` moves the selection, `Esc` closes it.
|
|
|
449
526
|
| `Esc` again after interruption | **Force-stop** a run that is still stopping, kill foreground shell commands and return to `idle`; background services remain running |
|
|
450
527
|
| `Ctrl+C` | **Copy the selection** when a drag-selection is waiting (release no longer copies by itself). Otherwise: stop the background **services** the agent started, when there are any. It does not arm exit |
|
|
451
528
|
| `Ctrl+C` ×2 | Exit (first press warns), once no services are running |
|
|
452
|
-
| `Ctrl+L` |
|
|
529
|
+
| `Ctrl+L` | **Branch this session into a new terminal**: opens a PowerShell (Windows) or bash (macOS/Linux) window at the current `/cwd` and runs `aragon --resume <id>` there, so the branch gets its own id and the session you branched from is untouched. Works while the agent is running - the child inherits the last settled turn. Same code path as `/branch` |
|
|
530
|
+
| `Ctrl+R` | Redraw the frame (moved here from `Ctrl+L`, which is now the branch key) |
|
|
453
531
|
| `Ctrl+T` | Show / hide thinking (**off by default**) for the entire session |
|
|
454
532
|
| `Ctrl+O` | Expand / collapse the most recent tool, team, compaction or **service** card — including a diff or a service's log tail |
|
|
455
533
|
| `PgUp` / `PgDn` | Scroll the transcript a page (full-screen mode) |
|
|
@@ -1103,6 +1181,10 @@ all reap the tree on a best-effort basis; there is no daemon, no PID file and no
|
|
|
1103
1181
|
reattach across launches. A `SIGKILL` of aragon itself is unrecoverable by
|
|
1104
1182
|
construction, and if a stop cannot confirm the process is gone it says
|
|
1105
1183
|
`may have left a detached child` rather than claiming success.
|
|
1184
|
+
**A branch window is the deliberate exception.** `Ctrl+L` (see [Branch into a
|
|
1185
|
+
new terminal](#branch-into-a-new-terminal---ctrll)) starts a process that is
|
|
1186
|
+
not registered with the supervisor, so it is not a service: it is another
|
|
1187
|
+
session the user opened, and it keeps running after this window exits.
|
|
1106
1188
|
|
|
1107
1189
|
From your side there are two keys and one command: `Ctrl+C` stops every live
|
|
1108
1190
|
service (and does *not* arm exit), `/bg` lists them, and `/bg logs s1` prints a
|
|
@@ -1720,6 +1802,70 @@ running, `Ctrl+I` warns instead of queueing. `/skill:project-indexer` and
|
|
|
1720
1802
|
> is distinguishable and the binding works. On a terminal that implements
|
|
1721
1803
|
> neither, `Ctrl+I` simply behaves as `Tab`.
|
|
1722
1804
|
|
|
1805
|
+
### Branch into a new terminal - `Ctrl+L`
|
|
1806
|
+
|
|
1807
|
+
Handing a conversation to a second window used to mean reading six characters off
|
|
1808
|
+
the status bar, switching windows, opening a shell and typing the command - and
|
|
1809
|
+
copying the id by hand is the one step of that chain which reliably goes wrong.
|
|
1810
|
+
`Ctrl+L` replaces it with one keystroke:
|
|
1811
|
+
|
|
1812
|
+
1. The session is **flushed to disk first**. A child process reads that file as its
|
|
1813
|
+
first act, and the parent's checkpoint is debounced, so the write is forced
|
|
1814
|
+
before anything is spawned (`--resume` reads the file, never the running process).
|
|
1815
|
+
2. A new terminal opens **in the current `/cwd`** - not in `$HOME` and not in the
|
|
1816
|
+
directory aragon was launched from: `/cwd` can change during a session, and
|
|
1817
|
+
`--resume` does not restore a working directory. Each platform carries the path
|
|
1818
|
+
itself: `wt -d <cwd>` for a Windows Terminal tab, `cmd /c start` for a plain
|
|
1819
|
+
console (which inherits it), and a script that begins with `cd '<cwd>' &&` for
|
|
1820
|
+
macOS Terminal and the Linux emulators.
|
|
1821
|
+
3. It runs `aragon --resume <id>` there. The child derives its own id, prints
|
|
1822
|
+
`Resumed <id> as a new branch: session <new-id>`, and writes only its own file.
|
|
1823
|
+
|
|
1824
|
+
Both windows are independent from that point: closing either one does not touch the
|
|
1825
|
+
other, `Ctrl+C` in the parent does not stop the branch, and the two transcripts
|
|
1826
|
+
never meet. **A branch window is another session and does not close when this one
|
|
1827
|
+
exits** (the reverse of the rule for supervised services below).
|
|
1828
|
+
|
|
1829
|
+
The platform ladder, in order:
|
|
1830
|
+
|
|
1831
|
+
| Platform | What is tried | Window |
|
|
1832
|
+
| --- | --- | --- |
|
|
1833
|
+
| Windows, inside Windows Terminal (`WT_SESSION` is set) | `wt -w 0 nt -d <cwd> --title "aragon <id>" -- <shell> -NoExit -EncodedCommand <base64>` | a new tab |
|
|
1834
|
+
| Windows, anywhere else | `cmd /d /s /c start "aragon <id>" <shell> -NoExit -EncodedCommand <base64>` | a new console window |
|
|
1835
|
+
| macOS | `osascript` driving Terminal.app | a new Terminal window |
|
|
1836
|
+
| Linux / other POSIX | the first of `$TERMINAL`, `x-terminal-emulator`, `gnome-terminal`, `konsole`, `xfce4-terminal`, `kitty`, `wezterm`, `alacritty`, `xterm` that exists | a new window |
|
|
1837
|
+
|
|
1838
|
+
The shell is `pwsh.exe` then `powershell.exe` on Windows, and `$SHELL` then `bash`
|
|
1839
|
+
then `/bin/sh` elsewhere. Windows receives the command as `-EncodedCommand` (base64
|
|
1840
|
+
of UTF-16LE), because that alphabet has no spaces, quotes or `cmd` metacharacters -
|
|
1841
|
+
it survives `cmd` -> `start` -> PowerShell without a quoting argument.
|
|
1842
|
+
|
|
1843
|
+
When no terminal can be opened - an SSH session, a container, a machine with no
|
|
1844
|
+
graphical session - the command opens nothing and prints the fallback instead:
|
|
1845
|
+
|
|
1846
|
+
```
|
|
1847
|
+
No terminal window could be opened here. Run this in another terminal:
|
|
1848
|
+
aragon --resume a4k2m9
|
|
1849
|
+
```
|
|
1850
|
+
|
|
1851
|
+
Two environment variables exist because neither belongs in a config file:
|
|
1852
|
+
|
|
1853
|
+
| Variable | Effect |
|
|
1854
|
+
| --- | --- |
|
|
1855
|
+
| `ARAGON_BRANCH_COMMAND` | What the new window executes, as **one executable path** (no arguments - wrap a script in a `.cmd` / `.sh` if you need some). Defaults to the running build: `node <dist/cli.js>`, or `aragon` from `PATH` |
|
|
1856
|
+
| `ARAGON_BRANCH_SHELL` | The shell the new window runs. `C:\Program Files\PowerShell\7\pwsh.exe`, `/usr/bin/fish`, ... |
|
|
1857
|
+
|
|
1858
|
+
Notes worth knowing:
|
|
1859
|
+
|
|
1860
|
+
- The key leaves **one** line in the transcript, `Command: /branch`, and it joins
|
|
1861
|
+
the prompt history. That is the same behaviour as `Ctrl+I` and it is what makes
|
|
1862
|
+
the gesture a real command: `Esc` never has to cancel it, `/help` lists it, and
|
|
1863
|
+
`/branch` typed by hand is byte-for-byte the same path (cooldown included).
|
|
1864
|
+
- Repeated presses are throttled to one window every two seconds; a press that
|
|
1865
|
+
**failed** does not start the cooldown, so the retry is immediate.
|
|
1866
|
+
- `/session copy` is still there for the case this key cannot cover: copying the
|
|
1867
|
+
command for a machine that is not this one.
|
|
1868
|
+
|
|
1723
1869
|
### Progressive disclosure
|
|
1724
1870
|
|
|
1725
1871
|
This is the part that makes skills cheap enough to install a lot of:
|
|
@@ -2289,7 +2435,7 @@ Everything AragonAgent keeps for you lives under one directory in your home:
|
|
|
2289
2435
|
├── logs/
|
|
2290
2436
|
│ ├── aragon-2026-07-27.log today, JSON Lines
|
|
2291
2437
|
│ └── aragon-2026-07-27.1.log rotated at log.maxFileBytes
|
|
2292
|
-
├── sessions/ /save
|
|
2438
|
+
├── sessions/ session checkpoints, /save exports, exec sessions
|
|
2293
2439
|
├── skills/ aragon skills install
|
|
2294
2440
|
└── skill-usage.json
|
|
2295
2441
|
```
|
|
@@ -2519,6 +2665,12 @@ Queue 面板逐条显示待处理消息,数量在展开状态详情中按空
|
|
|
2519
2665
|
费用是含子代理、快速模型及压缩的会话估算 USD,恢复会话沿用累计,缺价格按零计,零值不保证免费。
|
|
2520
2666
|
本轮均速只累计主 Agent 已报告的 output tokens,再除以本轮总耗时(含工具与等待);排除辅助调用,并非瞬时生成速度。结束后保留耗时,速度显示 --。
|
|
2521
2667
|
`/context` 提供统计范围和完整值。
|
|
2668
|
+
Ctrl+L 把当前会话分支到一个新终端:先强制落盘,再在父 TUI 的 `/cwd` 下打开 PowerShell(Windows)
|
|
2669
|
+
或 bash(macOS/Linux)窗口,在其中执行 `aragon --resume <id>`,子会话派生自己的新 id,原会话的 id、
|
|
2670
|
+
历史与文件都不受影响;运行中同样可用,子会话继承到上一个已落定的轮次。重绘迁到 Ctrl+R,
|
|
2671
|
+
右上角常驻 `^L branch` 提示(窄终端先丢 `^I`、再只留 `^L`)。每次按键会在转录里留下一行
|
|
2672
|
+
`Command: /branch`,并进入提示历史,与 Ctrl+I 完全同构。没有可用终端时只打印一条可粘贴的
|
|
2673
|
+
`aragon --resume <id>`,不会静默失败。
|
|
2522
2674
|
|
|
2523
2675
|
Windows Terminal:在设置 JSON **根级**添加 `"copyOnSelect": false`,把以下条目合并到已有数组:
|
|
2524
2676
|
|
package/dist/agent/reducer.d.ts
CHANGED
|
@@ -385,6 +385,14 @@ export interface ViewState {
|
|
|
385
385
|
*/
|
|
386
386
|
droppedEntries: number;
|
|
387
387
|
}
|
|
388
|
+
/**
|
|
389
|
+
* The zero session total.
|
|
390
|
+
*
|
|
391
|
+
* ONE LITERAL FOR TWO SITES (`initialViewState` and `resetConversation`). They
|
|
392
|
+
* used to spell the object out twice, which is how `cacheReadTokens` would have
|
|
393
|
+
* been added to one of them and not the other.
|
|
394
|
+
*/
|
|
395
|
+
export declare const EMPTY_USAGE_TOTAL: UsageTotal;
|
|
388
396
|
export interface ViewStateSeed {
|
|
389
397
|
/** Start with thinking blocks expanded. Defaults to FALSE, the product default. */
|
|
390
398
|
thinkingVisible?: boolean;
|
|
@@ -490,6 +498,20 @@ export type ViewAction = {
|
|
|
490
498
|
type: 'clearTranscript';
|
|
491
499
|
} | {
|
|
492
500
|
type: 'resetConversation';
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Zero the session's spend WITHOUT touching the conversation
|
|
504
|
+
* (tui-session-id-resume D-10 / R-9 / T-45).
|
|
505
|
+
*
|
|
506
|
+
* A separate action rather than `resetConversation`, because the two mean
|
|
507
|
+
* different things: `/clear` ends the conversation and the spend together,
|
|
508
|
+
* while an in-TUI `/resume` adopts another conversation and starts a NEW id -
|
|
509
|
+
* so the counter must restart, but the entries that were just restored must
|
|
510
|
+
* not be thrown away with it. `context` is left untouched for the reason
|
|
511
|
+
* `resetConversation` records: the meter, not the reducer, owns occupancy.
|
|
512
|
+
*/
|
|
513
|
+
| {
|
|
514
|
+
type: 'resetUsage';
|
|
493
515
|
} | {
|
|
494
516
|
type: 'setOverlay';
|
|
495
517
|
overlay: Overlay;
|
package/dist/agent/reducer.js
CHANGED
|
@@ -24,7 +24,7 @@ export const DEFAULT_TOAST_TTL_MS = 2500;
|
|
|
24
24
|
* used to spell the object out twice, which is how `cacheReadTokens` would have
|
|
25
25
|
* been added to one of them and not the other.
|
|
26
26
|
*/
|
|
27
|
-
const EMPTY_USAGE_TOTAL = {
|
|
27
|
+
export const EMPTY_USAGE_TOTAL = {
|
|
28
28
|
inputTokens: 0,
|
|
29
29
|
outputTokens: 0,
|
|
30
30
|
cacheReadTokens: 0,
|
|
@@ -809,6 +809,9 @@ export function viewReducer(state, action) {
|
|
|
809
809
|
// still running. `/clear screen` clears the screen, not the session.
|
|
810
810
|
compactionEntryId: undefined,
|
|
811
811
|
};
|
|
812
|
+
case 'resetUsage':
|
|
813
|
+
// The one field, for the one reason: a new id bills from zero (D-10).
|
|
814
|
+
return { ...state, usageTotal: EMPTY_USAGE_TOTAL };
|
|
812
815
|
case 'resetConversation':
|
|
813
816
|
return {
|
|
814
817
|
...state,
|