@aragon-agent/cli 0.6.34 → 0.6.36

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 (185) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +173 -7
  3. package/dist/agent/agent-mode.d.ts +20 -4
  4. package/dist/agent/agent-mode.js +20 -4
  5. package/dist/agent/controller.d.ts +67 -3
  6. package/dist/agent/controller.js +106 -5
  7. package/dist/agent/headless.js +31 -0
  8. package/dist/agent/kit-apply.d.ts +56 -0
  9. package/dist/agent/kit-apply.js +209 -0
  10. package/dist/agent/model-profile-settings.d.ts +28 -0
  11. package/dist/agent/model-profile-settings.js +142 -29
  12. package/dist/agent/reducer.d.ts +13 -2
  13. package/dist/agent/reducer.js +1 -0
  14. package/dist/cli.js +12 -0
  15. package/dist/commands/agents-command.d.ts +15 -0
  16. package/dist/commands/agents-command.js +27 -0
  17. package/dist/commands/builtins.js +135 -4
  18. package/dist/commands/kit-command.d.ts +20 -0
  19. package/dist/commands/kit-command.js +131 -0
  20. package/dist/commands/perf.d.ts +11 -0
  21. package/dist/commands/perf.js +2 -1
  22. package/dist/commands/registry.d.ts +14 -0
  23. package/dist/config/app-paths.d.ts +15 -0
  24. package/dist/config/app-paths.js +33 -2
  25. package/dist/config/env.d.ts +4 -1
  26. package/dist/config/env.js +28 -2
  27. package/dist/config/kit-resolution.d.ts +93 -0
  28. package/dist/config/kit-resolution.js +226 -0
  29. package/dist/config/load.d.ts +10 -0
  30. package/dist/config/load.js +8 -1
  31. package/dist/config/model-kits.d.ts +224 -0
  32. package/dist/config/model-kits.js +302 -0
  33. package/dist/config/model-profile-store.d.ts +25 -0
  34. package/dist/config/model-profiles.d.ts +41 -3
  35. package/dist/config/model-profiles.js +46 -5
  36. package/dist/config/schema.d.ts +84 -0
  37. package/dist/config/schema.js +39 -0
  38. package/dist/config/store.js +12 -1
  39. package/dist/config/ui-state.d.ts +18 -0
  40. package/dist/config/ui-state.js +9 -0
  41. package/dist/exec/events.d.ts +25 -0
  42. package/dist/exec/events.js +4 -0
  43. package/dist/exec/index.js +16 -1
  44. package/dist/exec/runner.js +10 -0
  45. package/dist/input/keymap.js +18 -4
  46. package/dist/proc/limits.d.ts +16 -0
  47. package/dist/proc/limits.js +16 -0
  48. package/dist/proc/supervisor.d.ts +20 -1
  49. package/dist/proc/supervisor.js +42 -14
  50. package/dist/prompts/command.d.ts +34 -0
  51. package/dist/prompts/command.js +237 -0
  52. package/dist/prompts/copy.d.ts +89 -0
  53. package/dist/prompts/copy.js +131 -0
  54. package/dist/prompts/fill.d.ts +51 -0
  55. package/dist/prompts/fill.js +46 -0
  56. package/dist/prompts/limits.d.ts +53 -0
  57. package/dist/prompts/limits.js +53 -0
  58. package/dist/prompts/normalize.d.ts +53 -0
  59. package/dist/prompts/normalize.js +190 -0
  60. package/dist/prompts/resolve.d.ts +31 -0
  61. package/dist/prompts/resolve.js +60 -0
  62. package/dist/prompts/search.d.ts +58 -0
  63. package/dist/prompts/search.js +146 -0
  64. package/dist/prompts/store.d.ts +86 -0
  65. package/dist/prompts/store.js +453 -0
  66. package/dist/prompts/types.d.ts +204 -0
  67. package/dist/prompts/types.js +13 -0
  68. package/dist/session/checkpoint.d.ts +8 -1
  69. package/dist/session/checkpoint.js +6 -0
  70. package/dist/session/persist.d.ts +19 -1
  71. package/dist/session/persist.js +13 -1
  72. package/dist/session/startup-session.d.ts +7 -2
  73. package/dist/session/startup-session.js +5 -2
  74. package/dist/session/store.js +3 -0
  75. package/dist/session/validate-session.js +64 -1
  76. package/dist/team/limits.d.ts +25 -0
  77. package/dist/team/limits.js +26 -0
  78. package/dist/team/runtime.js +27 -2
  79. package/dist/team/settled.d.ts +57 -0
  80. package/dist/team/settled.js +87 -0
  81. package/dist/team/subagent.js +48 -2
  82. package/dist/team/timeline.d.ts +74 -0
  83. package/dist/team/timeline.js +101 -0
  84. package/dist/team/types.d.ts +24 -1
  85. package/dist/todo/acceptance.d.ts +120 -0
  86. package/dist/todo/acceptance.js +399 -0
  87. package/dist/todo/follow-through.d.ts +48 -23
  88. package/dist/todo/follow-through.js +110 -44
  89. package/dist/todo/limits.d.ts +62 -1
  90. package/dist/todo/limits.js +62 -1
  91. package/dist/todo/panel-rows.d.ts +29 -39
  92. package/dist/todo/panel-rows.js +37 -83
  93. package/dist/todo/plan-sections.d.ts +60 -0
  94. package/dist/todo/plan-sections.js +108 -0
  95. package/dist/todo/prompt.d.ts +17 -12
  96. package/dist/todo/prompt.js +59 -40
  97. package/dist/todo/row-window.d.ts +51 -0
  98. package/dist/todo/row-window.js +107 -0
  99. package/dist/todo/store.d.ts +139 -31
  100. package/dist/todo/store.js +271 -73
  101. package/dist/todo/todo-tool.d.ts +33 -8
  102. package/dist/todo/todo-tool.js +186 -30
  103. package/dist/todo/types.d.ts +58 -0
  104. package/dist/ui/App.js +414 -54
  105. package/dist/ui/Composer.d.ts +6 -2
  106. package/dist/ui/Composer.js +2 -2
  107. package/dist/ui/Header.d.ts +17 -1
  108. package/dist/ui/Header.js +8 -2
  109. package/dist/ui/PromptInput.d.ts +21 -1
  110. package/dist/ui/PromptInput.js +22 -2
  111. package/dist/ui/ScrollbackShell.d.ts +22 -7
  112. package/dist/ui/ScrollbackShell.js +8 -1
  113. package/dist/ui/StatusBar.d.ts +18 -0
  114. package/dist/ui/StatusBar.js +11 -3
  115. package/dist/ui/TeamPanel.d.ts +35 -41
  116. package/dist/ui/TeamPanel.js +53 -163
  117. package/dist/ui/TodoPanel.d.ts +17 -14
  118. package/dist/ui/TodoPanel.js +146 -38
  119. package/dist/ui/Transcript.js +23 -3
  120. package/dist/ui/composer-input.d.ts +10 -0
  121. package/dist/ui/composer-input.js +57 -24
  122. package/dist/ui/entries/TeamCard.d.ts +18 -2
  123. package/dist/ui/entries/TeamCard.js +47 -13
  124. package/dist/ui/entries/TodoCard.d.ts +26 -11
  125. package/dist/ui/entries/TodoCard.js +56 -15
  126. package/dist/ui/glyphs.d.ts +19 -0
  127. package/dist/ui/glyphs.js +4 -0
  128. package/dist/ui/layout/agents-board.d.ts +102 -0
  129. package/dist/ui/layout/agents-board.js +389 -0
  130. package/dist/ui/layout/cells.d.ts +61 -0
  131. package/dist/ui/layout/cells.js +156 -0
  132. package/dist/ui/layout/header-hints.d.ts +23 -3
  133. package/dist/ui/layout/header-hints.js +73 -7
  134. package/dist/ui/layout/kit-chip.d.ts +50 -0
  135. package/dist/ui/layout/kit-chip.js +81 -0
  136. package/dist/ui/layout/status-detail-layout.js +9 -0
  137. package/dist/ui/layout/status-layout.d.ts +13 -0
  138. package/dist/ui/layout/team-row.d.ts +139 -0
  139. package/dist/ui/layout/team-row.js +246 -0
  140. package/dist/ui/layout/todo-layout.d.ts +38 -0
  141. package/dist/ui/layout/todo-layout.js +75 -0
  142. package/dist/ui/layout/virtual-window.js +32 -3
  143. package/dist/ui/overlays/AgentsBoardOverlay.d.ts +57 -0
  144. package/dist/ui/overlays/AgentsBoardOverlay.js +183 -0
  145. package/dist/ui/overlays/HelpOverlay.js +24 -2
  146. package/dist/ui/overlays/KitEditor.d.ts +23 -0
  147. package/dist/ui/overlays/KitEditor.js +101 -0
  148. package/dist/ui/overlays/KitManager.d.ts +23 -0
  149. package/dist/ui/overlays/KitManager.js +104 -0
  150. package/dist/ui/overlays/KitPicker.d.ts +49 -0
  151. package/dist/ui/overlays/KitPicker.js +58 -0
  152. package/dist/ui/overlays/ModelProfilePicker.js +16 -6
  153. package/dist/ui/overlays/PromptEditorPage.d.ts +48 -0
  154. package/dist/ui/overlays/PromptEditorPage.js +227 -0
  155. package/dist/ui/overlays/PromptLibraryOverlay.d.ts +37 -0
  156. package/dist/ui/overlays/PromptLibraryOverlay.js +191 -0
  157. package/dist/ui/overlays/PromptPicker.d.ts +36 -0
  158. package/dist/ui/overlays/PromptPicker.js +129 -0
  159. package/dist/ui/overlays/PromptTextArea.d.ts +86 -0
  160. package/dist/ui/overlays/PromptTextArea.js +141 -0
  161. package/dist/ui/overlays/SettingsScreen.js +139 -16
  162. package/dist/ui/overlays/kit-picker-state.d.ts +87 -0
  163. package/dist/ui/overlays/kit-picker-state.js +136 -0
  164. package/dist/ui/overlays/kit-settings-state.d.ts +129 -0
  165. package/dist/ui/overlays/kit-settings-state.js +267 -0
  166. package/dist/ui/overlays/model-profile-state.d.ts +26 -3
  167. package/dist/ui/overlays/model-profile-state.js +59 -6
  168. package/dist/ui/overlays/prompt-library-state.d.ts +162 -0
  169. package/dist/ui/overlays/prompt-library-state.js +335 -0
  170. package/dist/ui/overlays/prompt-picker-state.d.ts +71 -0
  171. package/dist/ui/overlays/prompt-picker-state.js +98 -0
  172. package/dist/ui/scrollback/LiveTail.d.ts +2 -2
  173. package/dist/ui/scrollback/LiveTail.js +7 -2
  174. package/dist/ui/scrollback/band.js +14 -1
  175. package/dist/ui/scrollback/live-preview.js +10 -3
  176. package/dist/ui/scrollback/tail-window.d.ts +12 -0
  177. package/dist/ui/scrollback/tail-window.js +17 -2
  178. package/dist/ui/scrollback/use-scrollback-view.js +7 -0
  179. package/dist/ui/team-status.d.ts +166 -0
  180. package/dist/ui/team-status.js +252 -0
  181. package/dist/ui/transcript-text.js +13 -4
  182. package/dist/ui/use-startup-notices.d.ts +35 -1
  183. package/dist/ui/use-startup-notices.js +29 -2
  184. package/dist/ui/use-wheel-routing.js +10 -2
  185. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -8,6 +8,27 @@ were written.
8
8
  ## Unreleased
9
9
 
10
10
  ### Added
11
+ - **Acceptance criteria: a plan now has to say how you would know it is done.**
12
+ `todo_write` takes a second array in the SAME call - one checkable statement per
13
+ line plus the check the model will run for it - so the steps and the criteria can
14
+ never drift apart. When every step is completed the plan enters a derived
15
+ **verify** phase: the model checks one criterion at a time and must record what it
16
+ actually saw, and a verdict without evidence drops back to unchecked. A verdict is
17
+ never undone by quietly omitting the criterion from the next list; re-checking one
18
+ takes `reopen: true` or `/todo acceptance reset`. The rail grows a second section
19
+ (`ACCEPT 2/5` while working, `VERIFY 2/5` once the steps are done, one `AC 2/5`
20
+ line on a short terminal), the transcript card lists the failed criteria with their
21
+ evidence, `/todo status` repeats the table, the status line carries `Accept 2/5`
22
+ when the rail cannot, `-p` prints one `[accept] 1/3 checked` line per transition,
23
+ and `aragon exec`'s `todo`/`result` events carry the counts (never the evidence).
24
+ "Every step is completed" is no longer the same claim as "the work is done": a new
25
+ `planIsResolved` judge decides the follow-through, the grace-window re-check and
26
+ the new-task clear together, and auto-continue counts a settled criterion as
27
+ progress so a plan is not abandoned after its second check. New `todo.acceptance`
28
+ key (`--todo-acceptance` / `--no-todo-acceptance` / `ARAGON_TODO_ACCEPTANCE` /
29
+ `/todo acceptance on|off|reset`, `todo-acceptance` capability); with it off every
30
+ surface is byte-identical to before. See
31
+ [Acceptance criteria](README.md#acceptance-criteria).
11
32
  - **Background jobs, and a bounded wait for them.** A command that finishes on its
12
33
  own but takes far longer than one tool call - `python train.py`,
13
34
  `huggingface-cli download`, `cargo build --release` - can now be started with
package/README.md CHANGED
@@ -23,7 +23,7 @@ full-screen mode (`--scroll-mode app`), where the application owns the mouse.
23
23
  **On Windows with Node < 22.17.0 (or 24.0/24.1), aragon turns the missing
24
24
  console flag on itself at startup**, which restores `Shift+Tab` on most
25
25
  machines. Where that is blocked — a locked-down PowerShell, an old console
26
- host — **`Ctrl+P` toggles the mode instead**; it is bound on every platform and
26
+ host — **`Ctrl+N` toggles the mode instead**; it is bound on every platform and
27
27
  does not depend on the console mode, the Node version, or anything else.
28
28
  Everything else — the agent loop, every tool, skills, teams, `aragon -p` — works
29
29
  exactly the same on Node 18 and 20, which is why `engines` stays at `>=18`
@@ -44,7 +44,7 @@ on. When that works, `Shift+Tab` arrives as `CSI Z` again and mouse reporting
44
44
  goes back on with it — the wheel should follow by the same route, though only
45
45
  the key has been measured. When it does not work, aragon says so at startup and
46
46
  turns mouse reporting off rather than asking for reports that can never arrive;
47
- `Ctrl+P` and `/plan` switch mode, and `Shift+↑` / `Shift+↓` scroll.
47
+ `Ctrl+N` and `/plan` switch mode, and `Shift+↑` / `Shift+↓` scroll.
48
48
 
49
49
  ## Install
50
50
 
@@ -389,6 +389,7 @@ below works there too, in either position — `aragon --model m exec "…"` and
389
389
  | `--todo` / `--no-todo` | Enable or disable todo planning. `--no-todo` does not register the `todo_write` tool at all |
390
390
  | `--todo-panel` / `--no-todo-panel` | Show or hide the right-hand todo rail. The tool stays registered either way |
391
391
  | `--todo-follow <mode>` | What happens when a run ends with steps left: `notify` (default), `auto`, `off` |
392
+ | `--todo-acceptance` / `--no-todo-acceptance` | Plan acceptance criteria with every list (the default) or steps only. Persisted, so the pair exists to keep "not passed" distinct from `true` |
392
393
  | `--retry` / `--no-retry` | Retry a failed provider call with backoff (the default), or fail on the first error |
393
394
  | `--retry-max <n>` | Retries after the first attempt for this run, clamped to `[0, 20]`. `0` turns retry off |
394
395
  | `--fast` / `--no-fast` | Enable or disable the fast model tier. Off by default; see **Fast model tier** |
@@ -480,6 +481,68 @@ displayed. `aragon --resume` of such a file inherits the full context and shows
480
481
  empty screen until the next turn - the alternative, inventing entries, would put
481
482
  a conversation the user never saw onto their screen.
482
483
 
484
+ ## Agent kits
485
+
486
+ A **kit** is a named preset that pins the three model roles at once: which
487
+ profile runs the main model, which runs the fast tier (or none), and which model
488
+ subagents use. It is a set of *references* to the profiles you already have, so
489
+ editing a profile changes every kit that names it — which is what "preset"
490
+ should mean.
491
+
492
+ Kits exist in three layers, and only one of them writes a file:
493
+
494
+ | Layer | Where | Lives until |
495
+ | --- | --- | --- |
496
+ | **Saved** | `/settings` → `Kit pack` → `New kit` / `e` | you delete it |
497
+ | **Default** | `Kit pack` → `s` (*Set default*), then `Ctrl+S` | you change it |
498
+ | **Session** | `Ctrl+K`, or `/kit use <name>` | this process exits |
499
+
500
+ The first row of the `Ctrl+K` overlay is always `Current setup` — the bindings in
501
+ `config.json` — and choosing it releases a session kit, so the feature has an exit
502
+ as well as an entrance.
503
+
504
+ ```
505
+ Agent kits Session only; set a default in /settings
506
+ [In use] Deep work [Default]
507
+ Current setup
508
+ ────────────────────────────────────────────────────────
509
+ main anthropic:claude-opus-4-6 default URL
510
+ subagent anthropic:claude-haiku-4-5 profile Haiku
511
+ fast anthropic:claude-haiku-4-5 tier on
512
+ ────────────────────────────────────────────────────────
513
+ Enter use for this session | Esc close
514
+ ```
515
+
516
+ - **`Ctrl+K` never writes the config file.** That is a promise with a test
517
+ behind it: the session path runs the same prepare chain as a save and skips
518
+ only the commit, so a failed switch leaves both the file and the session
519
+ exactly as they were, and a successful one produces no bytes on disk.
520
+ - **A save decides slots, not the whole kit.** Change the subagent model while a
521
+ session kit is in effect and only the subagent slot leaves the kit; main and
522
+ fast keep the kit's choices. Rebinding main releases main, and so on.
523
+ - **The status bar names what is running** with a `kit <name>` chip, and appends
524
+ `~` when the live connections no longer match the preset (for example after
525
+ `/model`). With no kit in effect the chip is not rendered at all.
526
+ - **`Ctrl+G` reveals `^K switch kit`** in the header row; on terminals narrower
527
+ than 79 columns it gives way to `^L` and `^I`, and `/help` plus `/kit` are the
528
+ fallback. (`Alt+K` is where `Ctrl+K`'s old "kill to end of line" went.)
529
+ - **Setting a default applies its three slots**, because "the default" *is* the
530
+ binding in the config file. A pointer alone would not be in effect at the next
531
+ launch.
532
+ - **Deleting a profile deletes the kits that name it**, in the same
533
+ confirmation, and says so: a preset pointing at a deleted profile can neither
534
+ be applied nor repaired from any screen. Kits that a hand-edited file leaves
535
+ dangling degrade to `Profile missing` and are refused with a stable message.
536
+
537
+ Config keys (all inside the existing `modelProfiles` section, so an older build
538
+ ignores them rather than rejecting the library):
539
+
540
+ | Key | Meaning |
541
+ | --- | --- |
542
+ | `modelProfiles.kits` | The library: id, name, main profile, fast profile (`null` = off), subagent mode + profile |
543
+ | `modelProfiles.defaultKitId` | The default kit, or `null`. A dangling value heals to `null` |
544
+ | `modelProfiles.kitsVersion` | Migration marker, always `1`. **Downgrading drops kits** (the older build's whitelist does not know the keys); profiles and bindings are unaffected, and `New kit` prefills from your current setup so rebuilding is one Save |
545
+
483
546
  ## Slash commands (interactive)
484
547
 
485
548
  | Command | Action |
@@ -489,6 +552,7 @@ a conversation the user never saw onto their screen.
489
552
  | `/settings` | Open the settings screen |
490
553
  | `/thinking <level>` | Set the thinking level |
491
554
  | `/max-tokens [<n>\|auto\|default]` | Output token cap; with no argument, reports the setting **and** the effective cap for the live model |
555
+ | `/agents` | Open the **subagent board**: every child of the current (or most recent) dispatch, its full facts, its result and its 24-event timeline. The same board as `Ctrl+B`. Read-only - it can never nudge, kill or re-dispatch a child |
492
556
  | `/tools` | List active tools |
493
557
  | `/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 |
494
558
  | `/reset` | Alias of `/clear` - one implementation, so the two cannot drift apart |
@@ -498,13 +562,15 @@ a conversation the user never saw onto their screen.
498
562
  | `/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 |
499
563
  | `/plan [on\|off\|status]` | Toggle plan mode - the keyboard-free equivalent of `Shift+Tab` |
500
564
  | `/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 |
501
- | `/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 |
565
+ | `/todo [on\|off\|panel on\|off\|follow <mode>\|acceptance on\|off\|reset\|clear\|continue]` | Todo planning: status, the on/off switch, the rail, follow-through, acceptance criteria, and picking an unfinished plan back up |
502
566
  | `/retry [show\|on\|off\|max <n>]` | API retry: the effective ladder, the on/off switch, the retry count. Takes effect **in the running session**, children included |
503
567
  | `/fast [on\|off\|model <id>\|provider <id>\|same\|review <n\|off>]` | Fast model tier: status and this session's totals, the on/off switch, which model, the review cadence |
504
568
  | `/compact [status\|on\|off\|threshold <n>\|keep <n>\|history\|show <n>\|<instructions>]` | Context compaction: occupancy and this session's totals, the on/off switch, when it fires, how much it keeps. With free text, compacts now and tells the summarizer what to pay attention to |
505
569
  | `/context` | What the context gauge is showing: occupancy split into measured and estimated, the window and **where it came from**, how stale the measurement is, compaction's actual state, and what the session-spend readout includes |
506
570
  | `/bg [list\|logs <id> [n]\|stop <id\|all>\|status]` | Background jobs (services and tasks): what is running, its log tail, and how to stop it. `list` is the default |
507
571
  | `/update [status\|now\|skip\|off]` | Auto-update: what is running, what is available, where it came from, when it looks again. `now` forces a check past the throttle; `skip` declines the offered version until a newer one appears |
572
+ | `/prompts [manage\|list\|show <n\|title>\|add [title :: body]\|edit <n\|title>\|rm <n\|title> [--yes]\|move <n\|title> <to>\|favorite <n\|title>\|sort name\|recent\|favorite]` | Quick prompt library: `/prompts` opens the picker (Enter fills the draft, `Ctrl+Enter` fills and sends), `add`/`edit` open the editor. `<n\|title>` accepts a 1-based index, an exact title, or a unique title prefix; a repeated title is refused **with its candidates** rather than guessed |
573
+ | `/kit [list\|use <name\|current>]` | Agent kits: what is in effect and where it came from, the whole library with each preset's three connections, or apply one for **this session**. `/kit use current` releases it. Never writes the config file |
508
574
  | `/theme <auto\|warm\|cool\|light>` | Switch the color theme live (persisted) |
509
575
  | `/expand [n]` | Expand / collapse the n-th-from-last (default last) tool card |
510
576
  | `/copy` | Copy the last answer to the clipboard |
@@ -526,8 +592,11 @@ completes, `Up` / `Down` moves the selection, `Esc` closes it.
526
592
  | `Enter` | 空闲时发送,运行时加入队列;收到 Core 已纳入会话的接收凭据后才移除 Queue 提示 |
527
593
  | `Ctrl+J` / `Alt+Enter` / `Shift+Enter` | 插入换行。应用默认请求终端区分修饰键(Windows 用 win32-input-mode,macOS/Linux 用 kitty/modifyOtherKeys),Shift+Enter 在支持的终端开箱即用;不支持的终端用 Ctrl+J。参见 [终端设置](#terminal-setup-for-shiftenter) |
528
594
  | `Shift+Tab` | Toggle **plan mode** (`BUILD` <-> `PLAN`). Equivalent: `/plan`. On Windows this needs a console flag Node < 22.17 does not set; aragon sets it at startup — see [Requirements](#requirements) |
529
- | `Ctrl+P` | The same toggle, over a channel no Windows console can swallow. Use it if `Shift+Tab` does nothing |
595
+ | `Ctrl+N` | The same toggle, over a channel no Windows console can swallow. Use it if `Shift+Tab` does nothing. Written `Ctrl+N` everywhere, never `^N` - `^N` is the header's line-offset chip |
596
+ | `Ctrl+P` | **Quick prompt library**: the manager - create, edit, delete, favourite and reorder your own prompts. See [Quick prompt library](#quick-prompt-library) |
597
+ | `Ctrl+B` | **Agents board**: the details of a running dispatch. Left column lists every child (not just the five the roster fits), the right-hand sections show the selected child's state, turns, tools, tokens, files, mail, supervisor actions, retries, compaction, its current activity, its final answer or error, and the last 24 events. `Up` / `Down` change the child, `PgUp` / `PgDn` and the wheel page, `Esc` closes. The board survives the end of the dispatch - it freezes the last live snapshot and marks it `dispatch ended` - and opens after the fact from the session's own team card, where everything except the live-only sections (current activity, mail count, timeline) is still readable. Pressing `Ctrl+B` again, or `/agents`, opens and closes it |
530
598
  | `Ctrl+I` | **Build the project index** (bundled `project-indexer` skill). Asks for confirmation, then runs as a normal agent turn that writes `.claude-index/` and updates `CLAUDE.md`. On terminals without keyboard enhancement `Ctrl+I` is the Tab byte and completes input instead |
599
+ | `Ctrl+K` | **Agent kits**: pick a model preset — main / subagent / fast profile in one choice — for **this session only**. Nothing is written to the config file. `Current setup` (the first row) releases the preset and returns to the file's bindings. See [Agent kits](#agent-kits) |
531
600
  | `Esc` | Close an overlay or popup; otherwise ask for interruption confirmation. While idle, cancel pending auto-continuation |
532
601
  | `Esc` ×2 | Interrupt the run when pressed within 1.5 seconds. Other keys or closing a menu cancel the first press |
533
602
  | `Esc` again after interruption | **Force-stop** a run that is still stopping, kill foreground shell commands and return to `idle`; background services remain running |
@@ -545,7 +614,7 @@ completes, `Up` / `Down` moves the selection, `Esc` closes it.
545
614
  | `Home` / `End`, `Ctrl+A` / `Ctrl+E` | Cursor to line start / end |
546
615
  | `Alt/Ctrl+←` / `→` | Word-wise cursor jump |
547
616
  | `Ctrl+W`, `Alt+Backspace` | Delete the previous word |
548
- | `Ctrl+U` / `Ctrl+K` | Kill to line start / end |
617
+ | `Ctrl+U` / `Alt+K` | Kill to line start / end (`Alt+K` was `Ctrl+K`, which now opens the kit picker) |
549
618
  | `Up` / `Down` | 按视觉行移动;空草稿或正在浏览历史时,才在边界召回历史,避免覆盖新草稿 |
550
619
  | Paste | Inserted up to 6 lines / 400 chars; larger collapses to `[Pasted text #1 +15 lines]`, which deletes as one unit and expands in full when you send. Escape sequences are removed as sequences (so a coloured log arrives as its text, not as `[38;2;18;52;86m`), and a TAB is kept in the payload but laid out at the terminal's 8-column tab stops, so the draft and the echoed message line up. `--no-paste` restores the pre-0.6.3 behaviour |
551
620
  | `?` | Open help (empty input) |
@@ -586,6 +655,47 @@ Turn the whole thing off with `--no-mouse`, `ARAGON_MOUSE=0`, or
586
655
  nothing in full-screen mode — it does not fall back to editing your draft, which
587
656
  is what it used to do. Inline mode is unaffected either way.
588
657
 
658
+ ## Quick prompt library
659
+
660
+ `↑` history remembers what you said. It does not remember what you say *every*
661
+ day. The prompt library is a small ordered collection of prompts you write
662
+ yourself - a title, a body, and optional tags, a note and a favourite flag -
663
+ that you can drop into the composer instead of retyping.
664
+
665
+ - **`Ctrl+P`** opens the manager. `Enter` edits the focused prompt, `a` creates
666
+ one, `d` deletes it (the confirmation page shows the body's size first), `f`
667
+ toggles favourite, and `Ctrl+`↑ / `Ctrl+`↓ move one prompt a position. The
668
+ order you see **is** the order on disk. In the editor, `Ctrl+S` saves and
669
+ `Tab` to the `Save` row then `Enter` does exactly the same thing - the second
670
+ path exists because a terminal can eat a `Ctrl` byte.
671
+ - **`/prompts`** opens the picker. Type to filter (`clr` finds
672
+ `clean code review`); `↑` / `↓` choose; `Enter` **fills the draft** without
673
+ sending it; `Ctrl+Enter` fills and sends in one step; `1`-`9` pick directly
674
+ while the query is empty; `Ctrl+S` cycles `manual` / `recent` / `favorite`;
675
+ `Tab` switches to the manager.
676
+ - **A fill never overwrites what you typed.** Into a non-empty draft it inserts
677
+ at the caret with a blank line between (`prompts.insertMode: 'replace'` does
678
+ overwrite if you prefer that), and it never becomes a `[Pasted text #1]`
679
+ token - an eight-line prompt arrives as eight lines.
680
+ - **Where it lives.** `~/.aragon-agent/quick-prompts.json`, written `0600` on
681
+ POSIX - not `config.json`, which is where an API key lives. An unreadable file
682
+ is copied to `quick-prompts.json.bak` and reported once; individual records
683
+ that cannot be parsed are skipped **and counted** rather than silently
684
+ dropped in bulk.
685
+ - **Where a key cannot be delivered.** `Ctrl+Enter` needs keyboard enhancement;
686
+ without it your terminal sends a plain `Enter`, so the prompt is filled and
687
+ you press `Enter` yourself. `Ctrl+`↑/↓ can lose its modifier on some
688
+ terminals - reordering is then always available as
689
+ `/prompts move <n> <to>`.
690
+
691
+ | Config key | Default | Meaning |
692
+ | --- | --- | --- |
693
+ | `prompts.enabled` | `true` | `false` stops `Ctrl+P` and the header hint. `/prompts` stays registered and reports that the library is off |
694
+ | `prompts.insertMode` | `insert` | What a fill does to a draft that already has text: `insert` keeps your words, `replace` overwrites them |
695
+ | `prompts.hint` | `true` | Whether the header's right-hand column teaches `^P prompts` |
696
+
697
+ `ARAGON_PROMPTS=0` is the same switch as `prompts.enabled: false`.
698
+
589
699
  ## Terminal setup for Shift+Enter
590
700
 
591
701
  应用现在会主动请求终端区分修饰键:Windows 上推送 win32-input-mode(conhost 与
@@ -1066,7 +1176,7 @@ it is an informed act rather than a stray keypress.
1066
1176
 
1067
1177
  ### If `Shift+Tab` does nothing
1068
1178
 
1069
- **Press `Ctrl+P`.** It is the same toggle and it does not depend on any of the
1179
+ **Press `Ctrl+N`.** It is the same toggle and it does not depend on any of the
1070
1180
  machinery below.
1071
1181
 
1072
1182
  To find out why, run this in the same terminal, press `Shift+Tab` once, then
@@ -1196,6 +1306,58 @@ planning discipline and hides the column — which is what you want with a scree
1196
1306
  reader, and what `--no-todo-panel` does for a whole session. Under `-p` the plan
1197
1307
  is written to stderr as `[todo] 3/7 <step>` lines, suppressed by `--quiet`.
1198
1308
 
1309
+ ### Acceptance criteria
1310
+
1311
+ A plan is a promise; the criteria are the evidence. Every plan therefore carries a
1312
+ second array — **how you will know each part is really done**, one checkable
1313
+ statement per line, each with the check the model intends to run:
1314
+
1315
+ ```jsonc
1316
+ { "todos": [ /* … */ ], "acceptance": [
1317
+ { "content": "the rail shows 3 items on an 80x24 terminal", "check": "resize and look" },
1318
+ { "content": "npm test -- runs green", "check": "npm test" } ] }
1319
+ ```
1320
+
1321
+ They arrive in the **same** `todo_write` call — one tool, one writer, one full
1322
+ replacement — so they cannot drift from the steps. Once every step is completed the
1323
+ plan enters **VERIFY**: the model checks one criterion at a time, and a verdict must
1324
+ name what it actually saw (`evidence`). A verdict without evidence drops back to
1325
+ unchecked. A verdict is *not* undone by quietly leaving the criterion out of the next
1326
+ list; re-checking one takes `reopen: true` (or `/todo acceptance reset`).
1327
+
1328
+ The rail grows a second section under the steps — `ACCEPT 2/5` while working,
1329
+ `VERIFY 2/5` once every step is done, folding to a single `AC 2/5` line when the
1330
+ terminal is short:
1331
+
1332
+ ```
1333
+ transcript ... | TODO 7/7
1334
+ | ####------
1335
+ |
1336
+ | all steps complete
1337
+ | VERIFY 2/5 !1
1338
+ | x npm test -- runs green
1339
+ | ! no console errors on startup
1340
+ | > README documents it
1341
+ ```
1342
+
1343
+ The failures are the point: the transcript card lists each failed criterion with the
1344
+ evidence under it, `/todo status` repeats the table on demand, and the status line
1345
+ carries `Accept 2/5` when the rail cannot. `-p` prints one `[accept] 1/3 checked`
1346
+ line per transition, and `aragon exec`'s `todo` and `result` events carry the same
1347
+ counts (never the evidence).
1348
+
1349
+ ```
1350
+ /todo acceptance show the criteria and every verdict so far
1351
+ /todo acceptance on|off plan criteria at all (persisted; default on)
1352
+ /todo acceptance reset send every verdict back to unchecked
1353
+ --todo-acceptance / --no-todo-acceptance, ARAGON_TODO_ACCEPTANCE
1354
+ todo.acceptance true | false in config.json
1355
+ ```
1356
+
1357
+ With `todo.acceptance: false` every surface — the prompt block, the tool's arguments
1358
+ and result text, the rail, the card, the `[accept]` lines and the exec fields — is
1359
+ byte-identical to a build without this feature, and a plan needs no criteria at all.
1360
+
1199
1361
  右栏从 76 列开始显示,正文至少保留 62 列;100 列终端使用 15 列右栏。
1200
1362
  已有任务时,团队面板按实际行数占用空间,补全菜单的边框和提示也计入预算。
1201
1363
  例如 100×20、团队占 8 行时,TODO 仍以 4 行紧凑视图显示。
@@ -2433,6 +2595,7 @@ env / `.env` → CLI flags**.
2433
2595
  `ARAGON_TEAM` (`0` disables team subagents), `ARAGON_TEAM_MAX` (fan-out width),
2434
2596
  `ARAGON_TODO` (`0` disables todo planning entirely),
2435
2597
  `ARAGON_TODO_FOLLOW` (`notify` / `auto` / `off`),
2598
+ `ARAGON_TODO_ACCEPTANCE` (`0` plans steps only: no criteria, no verify phase),
2436
2599
  `ARAGON_RETRY` (`0` disables API retry), `ARAGON_RETRY_MAX` (retry count; `0`
2437
2600
  also disables),
2438
2601
  `ARAGON_UPDATE` (`0` / `off` disables auto-update, `notify` reports without
@@ -2441,7 +2604,9 @@ env / `.env` → CLI flags**.
2441
2604
  `ARAGON_SKILLS_DISABLED` (comma-separated names), `ARAGON_LOG_LEVEL`,
2442
2605
  `ARAGON_LOG_FILE` (`0` disables), `ARAGON_LOG_DIR`,
2443
2606
  `ARAGON_TRANSCRIPT_RETAIN`, `ARAGON_RENDER_GOVERNOR` (`0` disables),
2444
- `ARAGON_MAX_RENDER_INTERVAL_MS`, `ARAGON_SCROLL_MODE` (`native` / `app`).
2607
+ `ARAGON_MAX_RENDER_INTERVAL_MS`, `ARAGON_SCROLL_MODE` (`native` / `app`),
2608
+ `ARAGON_PROMPTS` (`0` disables the quick prompt library: no `Ctrl+P`, no
2609
+ header hint; `/prompts` still reports that it is off).
2445
2610
  `ARAGON_HOME` is the exception that **cannot** come from `.env`: it is read
2446
2611
  before any `.env` is loaded. See [Files & logs](#files--logs).
2447
2612
  - **User config file** (`aragon config path`): JSON, written `0600` on POSIX.
@@ -2482,6 +2647,7 @@ env / `.env` → CLI flags**.
2482
2647
  | `todo.enabled` | `true` | Master switch for todo planning. `false` means the `todo_write` tool is never registered — `/todo on` in such a session saves the setting for next launch and says so, rather than advertising a tool that is not there. |
2483
2648
  | `todo.panel` | `true` | Render the right-hand rail. Independent of `todo.enabled` on purpose: a screen-reader user wants the planning discipline without the column, and the system prompt varies one sentence accordingly. |
2484
2649
  | `todo.followThrough` | `"notify"` | What happens when a run ends with steps left. `notify` says so and stops; `auto` continues the plan after a 3-second grace window, bounded by two structural limits (one fruitless attempt, 25 continuations per plan) that are deliberately **not** settings; `off` is silent. An unrecognized value falls back to `notify`. |
2650
+ | `todo.acceptance` | `true` | Plan acceptance criteria with every list, and show them (`ACCEPT` / `VERIFY` in the rail, the card's second block, `Accept 2/5` on the status line). `false` plans steps only: no criteria, no verify phase, and every surface is byte-identical to a build without the feature. `/todo acceptance off` changes it for the running session too. |
2485
2651
  | `retry.enabled` | `true` | Retry a failed provider call at all. Unlike `team.enabled` / `todo.enabled` this decides nothing at construction — the policy lives on the provider registry, so `/retry on` / `/retry off` takes effect **in the running session**, subagents included. |
2486
2652
  | `retry.maxRetries` | `10` | Retries **after** the first attempt, clamped to `[0, 20]`. `0` is the kill switch and is a real value here, not a typo for the default. The 20 is a hard ceiling enforced twice — on the config value and again inside the engine — so hand-editing this file cannot raise it. |
2487
2653
  | `retry.initialDelayMs` | `1000` | The first wait, clamped to `[100, 30000]`. |
@@ -41,17 +41,33 @@ export declare function nextMode(current: AgentMode): AgentMode;
41
41
  * PowerShell, a foreign process resetting the mode), so a rung that depends on
42
42
  * NOTHING has to exist underneath it.
43
43
  *
44
- * `ctrl+p` IS MEASURED, not guessed. On the lossy path it arrives as `0x10`,
44
+ * `ctrl+n` IS MEASURED, not guessed. On the lossy path it arrives as `0x0e`,
45
45
  * because Windows generates a real control character for `Ctrl+<letter>` and
46
46
  * libuv's character branch forwards it untouched; `Alt+M` produces no bytes at
47
47
  * all and `Ctrl+Tab` collapses exactly like `Shift+Tab` (analysis section 3.6).
48
48
  * Any idle `Ctrl+<letter>` in the `0x01-0x1A` range would work; this one is free
49
- * throughout the package - `keymap.ts` claims a/e/w/u/k, `App` claims c/l/t/o,
49
+ * throughout the package - `keymap.ts` claims a/e/w/u/k, `App` claims c/g/k/l/o/r/t,
50
50
  * and `PromptInput` returns early on every `key.ctrl` - so binding it takes no
51
51
  * behaviour away from anyone. `Ctrl+B` survives the same path but is tmux's
52
52
  * default prefix, and this binding is unconditional and cross-platform, so it
53
53
  * would be silently dead for a whole class of macOS and Linux users.
54
54
  *
55
+ * THIS KEY MOVED FROM `ctrl+p`, WHICH NOW OPENS THE PROMPT LIBRARY
56
+ * (quick-prompt-library D-1). The requirement names `ctrl+p` as the first entry
57
+ * to a feature users will build muscle memory for, and a key that is sometimes
58
+ * the prompt library and sometimes the mode switch is a key nobody can learn.
59
+ * `ctrl+n` was the only idle C0 byte left that survives the same lossy path, and
60
+ * it carries no conflicting behaviour: readline's `next-history` is `Up`/`Down`
61
+ * in this product.
62
+ *
63
+ * `^N` IS NOT AN ACCEPTABLE SPELLING OF IT, ANYWHERE. `^N` is already this
64
+ * product's word for TRANSCRIPT LINE OFFSET - the header's scroll chip reads
65
+ * `^<n>` and the help overlay has a `^N` row about the distance from the bottom -
66
+ * while every other `^X` in the same row is a key. Writing the mode fallback as
67
+ * `^N` would put two meanings of `^` on one line, so the header, the help
68
+ * overlay, `doctor`, the README and the one-shot migration notice all spell out
69
+ * `Ctrl+N`.
70
+ *
55
71
  * BOUND UNCONDITIONALLY, on every platform. A binding that only exists where it
56
72
  * is needed cannot be documented in one place, cannot be taught by muscle
57
73
  * memory, and is missing on precisely the machine whose capability probe was
@@ -59,13 +75,13 @@ export declare function nextMode(current: AgentMode): AgentMode;
59
75
  *
60
76
  * THESE ARE THE LABELS, NOT THE BINDING. Editing a value here changes only what
61
77
  * the user is TOLD to press - the hint row, the startup notice, `doctor`. The
62
- * key that is actually listened for is `input === 'p'` in `App`'s `useInput`,
78
+ * key that is actually listened for is `input === 'n'` in `App`'s `useInput`,
63
79
  * and the help overlay and README spell both keys out in their own title case.
64
80
  * Change one without the others and the product advertises a key it ignores.
65
81
  */
66
82
  export declare const MODE_TOGGLE_KEYS: {
67
83
  readonly primary: "shift+tab";
68
- readonly fallback: "ctrl+p";
84
+ readonly fallback: "ctrl+n";
69
85
  };
70
86
  /** The two tools that only exist because a human is attached. */
71
87
  export declare const PLAN_TOOL_NAMES: readonly ["ask_user", "submit_plan"];
@@ -43,17 +43,33 @@ export function nextMode(current) {
43
43
  * PowerShell, a foreign process resetting the mode), so a rung that depends on
44
44
  * NOTHING has to exist underneath it.
45
45
  *
46
- * `ctrl+p` IS MEASURED, not guessed. On the lossy path it arrives as `0x10`,
46
+ * `ctrl+n` IS MEASURED, not guessed. On the lossy path it arrives as `0x0e`,
47
47
  * because Windows generates a real control character for `Ctrl+<letter>` and
48
48
  * libuv's character branch forwards it untouched; `Alt+M` produces no bytes at
49
49
  * all and `Ctrl+Tab` collapses exactly like `Shift+Tab` (analysis section 3.6).
50
50
  * Any idle `Ctrl+<letter>` in the `0x01-0x1A` range would work; this one is free
51
- * throughout the package - `keymap.ts` claims a/e/w/u/k, `App` claims c/l/t/o,
51
+ * throughout the package - `keymap.ts` claims a/e/w/u/k, `App` claims c/g/k/l/o/r/t,
52
52
  * and `PromptInput` returns early on every `key.ctrl` - so binding it takes no
53
53
  * behaviour away from anyone. `Ctrl+B` survives the same path but is tmux's
54
54
  * default prefix, and this binding is unconditional and cross-platform, so it
55
55
  * would be silently dead for a whole class of macOS and Linux users.
56
56
  *
57
+ * THIS KEY MOVED FROM `ctrl+p`, WHICH NOW OPENS THE PROMPT LIBRARY
58
+ * (quick-prompt-library D-1). The requirement names `ctrl+p` as the first entry
59
+ * to a feature users will build muscle memory for, and a key that is sometimes
60
+ * the prompt library and sometimes the mode switch is a key nobody can learn.
61
+ * `ctrl+n` was the only idle C0 byte left that survives the same lossy path, and
62
+ * it carries no conflicting behaviour: readline's `next-history` is `Up`/`Down`
63
+ * in this product.
64
+ *
65
+ * `^N` IS NOT AN ACCEPTABLE SPELLING OF IT, ANYWHERE. `^N` is already this
66
+ * product's word for TRANSCRIPT LINE OFFSET - the header's scroll chip reads
67
+ * `^<n>` and the help overlay has a `^N` row about the distance from the bottom -
68
+ * while every other `^X` in the same row is a key. Writing the mode fallback as
69
+ * `^N` would put two meanings of `^` on one line, so the header, the help
70
+ * overlay, `doctor`, the README and the one-shot migration notice all spell out
71
+ * `Ctrl+N`.
72
+ *
57
73
  * BOUND UNCONDITIONALLY, on every platform. A binding that only exists where it
58
74
  * is needed cannot be documented in one place, cannot be taught by muscle
59
75
  * memory, and is missing on precisely the machine whose capability probe was
@@ -61,11 +77,11 @@ export function nextMode(current) {
61
77
  *
62
78
  * THESE ARE THE LABELS, NOT THE BINDING. Editing a value here changes only what
63
79
  * the user is TOLD to press - the hint row, the startup notice, `doctor`. The
64
- * key that is actually listened for is `input === 'p'` in `App`'s `useInput`,
80
+ * key that is actually listened for is `input === 'n'` in `App`'s `useInput`,
65
81
  * and the help overlay and README spell both keys out in their own title case.
66
82
  * Change one without the others and the product advertises a key it ignores.
67
83
  */
68
- export const MODE_TOGGLE_KEYS = { primary: 'shift+tab', fallback: 'ctrl+p' };
84
+ export const MODE_TOGGLE_KEYS = { primary: 'shift+tab', fallback: 'ctrl+n' };
69
85
  /** The two tools that only exist because a human is attached. */
70
86
  export const PLAN_TOOL_NAMES = ['ask_user', 'submit_plan'];
71
87
  /**
@@ -1,4 +1,6 @@
1
1
  import { type ModelSettingsSnapshot } from './model-profile-settings.js';
2
+ import { type ActiveKit } from '../config/kit-resolution.js';
3
+ import type { KitApplyResult } from '../config/model-kits.js';
2
4
  import type { ModelSettingsDraft, ModelSettingsPatch, ModelSettingsSaveResult } from '../config/model-profile-store.js';
3
5
  import { type CompactionIdentity } from '../compaction/memory-identity.js';
4
6
  /**
@@ -28,7 +30,7 @@ import { type FastStatus } from '../fast/wiring.js';
28
30
  import type { FastEventListener, FastSnapshot } from '../fast/types.js';
29
31
  import { ContextMeter, type ContextUsageListener } from '../compaction/meter.js';
30
32
  import type { CompactionEventListener, CompactionSnapshot, ContextUsageSnapshot } from '../compaction/types.js';
31
- import type { TodoEventListener, TodoSnapshot } from '../todo/types.js';
33
+ import type { AcceptanceItem, TodoEventListener, TodoSnapshot } from '../todo/types.js';
32
34
  import { type HumanInputGate } from '../tools/human-input.js';
33
35
  import { SkillService, type ApprovalGate } from '../skills/service.js';
34
36
  import { type ConversationResetOptions, type ConversationResetResult } from './conversation-reset.js';
@@ -585,6 +587,37 @@ export declare class AgentController {
585
587
  */
586
588
  setTodoConfig(patch: Partial<TodoConfig>): TodoConfig;
587
589
  getTodoSnapshot(): TodoSnapshot | null;
590
+ /**
591
+ * Whether the acceptance table is live for this session: the config key AND the
592
+ * session switch. Two flags, exactly as `isTodoEnabled` needs `isTodoRegistered`
593
+ * first - a capability that is on while `todo_write` refuses is not a
594
+ * capability.
595
+ */
596
+ isTodoAcceptanceEnabled(): boolean;
597
+ /**
598
+ * Flip the acceptance capability and RE-RENDER THE PROMPT, byte for byte the
599
+ * contract `setTodoEnabled` records above: the paragraph is part of
600
+ * `<todo_planning>`, and the tool reads the same live value through its
601
+ * `hasAcceptance` closure (D-11).
602
+ */
603
+ setTodoAcceptanceEnabled(enabled: boolean): void;
604
+ /**
605
+ * The acceptance table as DATA, independent of whether it is being drawn.
606
+ *
607
+ * The persistence surfaces must use this and not `getTodoSnapshot()?.acceptance`:
608
+ * the projection is `null` whenever the capability is off, and a checkpoint or a
609
+ * `/save` that silently dropped the user's verdicts because a display switch was
610
+ * off would be a data loss dressed as a setting.
611
+ */
612
+ getAcceptanceItems(): AcceptanceItem[];
613
+ /**
614
+ * `/todo acceptance reset`: every verdict back to `pending`, evidence dropped.
615
+ *
616
+ * The count comes BACK from the store rather than being recomputed by the
617
+ * command, so the notice and the state cannot disagree about how many criteria
618
+ * moved.
619
+ */
620
+ reopenAcceptance(): number;
588
621
  /**
589
622
  * Subscribe to the CLI-local todo event stream.
590
623
  *
@@ -592,8 +625,12 @@ export declare class AgentController {
592
625
  * every caller can subscribe unconditionally.
593
626
  */
594
627
  subscribeTodos(listener: TodoEventListener): () => void;
595
- /** `/resume`. An absent or empty list CLEARS — see `TodoStore.restore` (P0-2). */
596
- restoreTodos(items: unknown): void;
628
+ /**
629
+ * `/resume`. An absent or empty todo list CLEARS both tables — see
630
+ * `TodoStore.restore` (P0-2). `acceptance` is optional so every existing caller
631
+ * keeps compiling, and an omitted table reads as "this file has none".
632
+ */
633
+ restoreTodos(items: unknown, acceptance?: unknown): void;
597
634
  /**
598
635
  * `/todo clear` and `/clear screen`. A user override of a projection (I-2's
599
636
  * standing exception). `/todo` refuses mid-run before it gets here;
@@ -629,6 +666,33 @@ export declare class AgentController {
629
666
  saveModelSettingsPatch(patch: ModelSettingsPatch): ModelSettingsSaveResult;
630
667
  /** Refresh both role connections and credentials while retaining conversation state. */
631
668
  reloadModelSettings(): ModelSettingsSaveResult;
669
+ /**
670
+ * The narrow port `agent/kit-apply.ts` runs against (agent-model-kits §6.3).
671
+ *
672
+ * A LITERAL ADAPTER RATHER THAN `this`: the port's member names (`isBusy`,
673
+ * `hasKey`, `preview`) are deliberately NOT the controller's names, because a
674
+ * port that shadows a public method is one signature change away from silently
675
+ * calling itself. Three of the five members are one-liners onto existing
676
+ * methods; nothing here is new state.
677
+ */
678
+ private kitApplyPort;
679
+ /**
680
+ * Apply a kit for THIS SESSION ONLY (D-7 / I-5): no commit, ever.
681
+ *
682
+ * Failed applies leave the live config and the file untouched (I-10), because
683
+ * the whole operation is one prepare-and-apply with no commit in between.
684
+ */
685
+ applySessionKit(kitId: string): KitApplyResult;
686
+ /** Release the session kit and return to the config file's bindings (RV-P1-6). */
687
+ clearSessionKit(): KitApplyResult;
688
+ /**
689
+ * Which kit is in effect right now (session > default > disk bindings).
690
+ *
691
+ * DERIVED, never stored (D-5): the header chip, the settings root row and
692
+ * `/kit` all read this, so there is exactly one answer to "which preset am I
693
+ * running" and no copy of it that can drift.
694
+ */
695
+ getActiveKit(): ActiveKit;
632
696
  /** Prebuild all potentially failing model/prompt work before committing the file. */
633
697
  prepareModelSettingsSnapshot(config: CliConfig): ModelSettingsSnapshot;
634
698
  /** Apply prepared state synchronously, without rebuilding the controller or its history. */