@aragon-agent/cli 0.6.11 → 0.6.13

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 (115) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +97 -20
  3. package/dist/agent/controller.d.ts +38 -3
  4. package/dist/agent/controller.js +151 -60
  5. package/dist/agent/model-profile-settings.d.ts +31 -0
  6. package/dist/agent/model-profile-settings.js +199 -0
  7. package/dist/agent/queued-messages.d.ts +20 -0
  8. package/dist/agent/queued-messages.js +46 -0
  9. package/dist/agent/reducer.d.ts +21 -2
  10. package/dist/agent/reducer.js +65 -37
  11. package/dist/cli.js +15 -1
  12. package/dist/commands/builtins.js +83 -42
  13. package/dist/commands/queue-command.d.ts +3 -0
  14. package/dist/commands/queue-command.js +5 -0
  15. package/dist/commands/registry.d.ts +3 -0
  16. package/dist/compaction/child.d.ts +4 -2
  17. package/dist/compaction/child.js +4 -1
  18. package/dist/compaction/compactor.d.ts +7 -2
  19. package/dist/compaction/compactor.js +13 -11
  20. package/dist/compaction/context-command.js +5 -0
  21. package/dist/compaction/wiring.d.ts +4 -3
  22. package/dist/compaction/wiring.js +6 -1
  23. package/dist/config/cli-commands.d.ts +2 -0
  24. package/dist/config/cli-commands.js +16 -4
  25. package/dist/config/load.d.ts +2 -1
  26. package/dist/config/load.js +15 -8
  27. package/dist/config/model-profile-resolution.d.ts +20 -0
  28. package/dist/config/model-profile-resolution.js +81 -0
  29. package/dist/config/model-profile-store.d.ts +67 -0
  30. package/dist/config/model-profile-store.js +153 -0
  31. package/dist/config/model-profiles.d.ts +44 -0
  32. package/dist/config/model-profiles.js +121 -0
  33. package/dist/config/schema.d.ts +9 -0
  34. package/dist/config/store.d.ts +11 -1
  35. package/dist/config/store.js +43 -27
  36. package/dist/fast/resolve.d.ts +2 -1
  37. package/dist/fast/resolve.js +6 -4
  38. package/dist/fast/wiring.d.ts +5 -3
  39. package/dist/fast/wiring.js +8 -4
  40. package/dist/input/enter-sequences.d.ts +11 -10
  41. package/dist/input/enter-sequences.js +29 -27
  42. package/dist/input/stdin-filter.js +93 -28
  43. package/dist/logging/install.d.ts +3 -0
  44. package/dist/logging/install.js +4 -2
  45. package/dist/logging/secret-registry.d.ts +2 -0
  46. package/dist/logging/secret-registry.js +18 -0
  47. package/dist/session/persist.d.ts +6 -7
  48. package/dist/session/persist.js +6 -9
  49. package/dist/session/store.d.ts +4 -1
  50. package/dist/session/validate-session.d.ts +3 -0
  51. package/dist/session/validate-session.js +207 -0
  52. package/dist/team/runtime.d.ts +2 -1
  53. package/dist/team/subagent.d.ts +3 -1
  54. package/dist/team/subagent.js +3 -1
  55. package/dist/ui/ActivityLine.d.ts +6 -70
  56. package/dist/ui/ActivityLine.js +12 -34
  57. package/dist/ui/App.d.ts +1 -0
  58. package/dist/ui/App.js +161 -226
  59. package/dist/ui/BottomStatusRow.d.ts +6 -86
  60. package/dist/ui/BottomStatusRow.js +11 -26
  61. package/dist/ui/Composer.d.ts +18 -84
  62. package/dist/ui/Composer.js +9 -100
  63. package/dist/ui/PromptInput.d.ts +6 -2
  64. package/dist/ui/PromptInput.js +91 -105
  65. package/dist/ui/QueuePanel.d.ts +8 -0
  66. package/dist/ui/QueuePanel.js +9 -0
  67. package/dist/ui/QueueStatusRow.d.ts +24 -0
  68. package/dist/ui/QueueStatusRow.js +51 -0
  69. package/dist/ui/StatusBar.d.ts +15 -149
  70. package/dist/ui/StatusBar.js +27 -112
  71. package/dist/ui/clipboard-task.d.ts +29 -0
  72. package/dist/ui/clipboard-task.js +66 -0
  73. package/dist/ui/clipboard.d.ts +29 -50
  74. package/dist/ui/clipboard.js +141 -75
  75. package/dist/ui/composer-input.d.ts +28 -0
  76. package/dist/ui/composer-input.js +46 -0
  77. package/dist/ui/composer-limits.d.ts +3 -4
  78. package/dist/ui/composer-limits.js +4 -9
  79. package/dist/ui/composer-rows.d.ts +1 -1
  80. package/dist/ui/composer-rows.js +24 -137
  81. package/dist/ui/editor-navigation.d.ts +45 -0
  82. package/dist/ui/editor-navigation.js +85 -0
  83. package/dist/ui/editor-reducer.d.ts +9 -0
  84. package/dist/ui/editor-reducer.js +31 -15
  85. package/dist/ui/enter-frames.d.ts +15 -31
  86. package/dist/ui/enter-frames.js +14 -33
  87. package/dist/ui/interaction-copy.d.ts +77 -0
  88. package/dist/ui/interaction-copy.js +40 -0
  89. package/dist/ui/interaction-hints.d.ts +18 -0
  90. package/dist/ui/interaction-hints.js +92 -0
  91. package/dist/ui/layout/budget.js +1 -1
  92. package/dist/ui/layout/queue-layout.d.ts +19 -0
  93. package/dist/ui/layout/queue-layout.js +26 -0
  94. package/dist/ui/layout/status-layout.d.ts +55 -0
  95. package/dist/ui/layout/status-layout.js +109 -0
  96. package/dist/ui/layout/todo-layout.d.ts +1 -0
  97. package/dist/ui/layout/todo-layout.js +1 -1
  98. package/dist/ui/overlays/HelpOverlay.js +11 -3
  99. package/dist/ui/overlays/ModelProfileEditor.d.ts +12 -0
  100. package/dist/ui/overlays/ModelProfileEditor.js +103 -0
  101. package/dist/ui/overlays/ModelProfilePicker.d.ts +35 -0
  102. package/dist/ui/overlays/ModelProfilePicker.js +167 -0
  103. package/dist/ui/overlays/QueueOverlay.d.ts +22 -0
  104. package/dist/ui/overlays/QueueOverlay.js +79 -0
  105. package/dist/ui/overlays/SettingsScreen.d.ts +9 -2
  106. package/dist/ui/overlays/SettingsScreen.js +347 -3
  107. package/dist/ui/overlays/model-profile-state.d.ts +74 -0
  108. package/dist/ui/overlays/model-profile-state.js +119 -0
  109. package/dist/ui/run-status-row.d.ts +7 -19
  110. package/dist/ui/run-status-row.js +2 -18
  111. package/dist/ui/selection/selection-controller.d.ts +2 -2
  112. package/dist/ui/selection/selection-controller.js +58 -20
  113. package/dist/ui/transcript-text.js +20 -12
  114. package/dist/ui/use-wheel-routing.js +2 -1
  115. package/package.json +2 -2
@@ -27,9 +27,10 @@
27
27
  * same `decorate` call. What you see is what you get by construction, rather
28
28
  * than by a staleness check that can be wrong.
29
29
  */
30
+ import stripAnsi from 'strip-ansi';
30
31
  import { createScreenMirror } from './screen-mirror.js';
31
32
  import { paintRow, selectionOpen } from './highlight.js';
32
- import { isEmpty, normalize, rowSpan, selectedText, } from './selection.js';
33
+ import { isEmpty, normalize, rowSpan, selectedText, sliceColumns, } from './selection.js';
33
34
  /**
34
35
  * Motion coalescing window. The same 16 ms and the same reasoning as
35
36
  * `use-wheel-routing.ts`: this one is in the direct path of a hand gesture, so
@@ -67,10 +68,28 @@ export function createSelectionController(options) {
67
68
  let disposed = false;
68
69
  /** Guards `decorate` against being re-entered from inside a repaint. */
69
70
  let painting = false;
71
+ let notifiedHold = false;
72
+ let holdNotificationPending = false;
73
+ const notifyHold = () => {
74
+ if (disposed || notifiedHold === holdActive)
75
+ return;
76
+ notifiedHold = holdActive;
77
+ for (const listener of [...holdListeners])
78
+ listener(holdActive);
79
+ };
70
80
  const emitHold = (hold) => {
71
81
  holdActive = hold;
72
- for (const listener of [...holdListeners])
73
- listener(hold);
82
+ if (!painting) {
83
+ notifyHold();
84
+ return;
85
+ }
86
+ if (holdNotificationPending)
87
+ return;
88
+ holdNotificationPending = true;
89
+ queueMicrotask(() => {
90
+ holdNotificationPending = false;
91
+ notifyHold();
92
+ });
74
93
  };
75
94
  const clearFlushTimer = () => {
76
95
  if (!flushTimer)
@@ -97,13 +116,7 @@ export function createSelectionController(options) {
97
116
  holdWatchdog = null;
98
117
  if (!dragging)
99
118
  return;
100
- // Let go of `hold` and the drag; KEEP whatever was selected. The user may
101
- // still want to copy it, and throwing it away would turn a terminal quirk
102
- // into lost work.
103
- dragging = false;
104
- pendingFocus = null;
105
- clearFlushTimer();
106
- emitHold(false);
119
+ clear();
107
120
  }, holdMaxMs);
108
121
  holdWatchdog.unref?.();
109
122
  };
@@ -122,7 +135,7 @@ export function createSelectionController(options) {
122
135
  if (!painted && wanted)
123
136
  options.requestRedraw();
124
137
  };
125
- const clear = () => {
138
+ const clearState = () => {
126
139
  // Nothing to undo: no timers, no repaint, no redraw. This is what keeps
127
140
  // `onInvalidate` — which fires on every resize and every foreign write —
128
141
  // free for a session that has never selected anything.
@@ -139,7 +152,12 @@ export function createSelectionController(options) {
139
152
  // exit for two states, not one.
140
153
  if (holdActive)
141
154
  emitHold(false);
142
- paint(false);
155
+ };
156
+ const clear = () => {
157
+ const hadSelection = sel !== null || holdActive;
158
+ clearState();
159
+ if (hadSelection)
160
+ paint(false);
143
161
  };
144
162
  const cellOf = (event) => {
145
163
  // SGR reports are 1-based, frame line `i` is terminal row `i + 1`. A report
@@ -191,6 +209,7 @@ export function createSelectionController(options) {
191
209
  // key, resize, overlay, /mouse off).
192
210
  settled = true;
193
211
  paint(true);
212
+ options.requestRedraw();
194
213
  };
195
214
  const onMouse = (event) => {
196
215
  if (disposed)
@@ -200,8 +219,7 @@ export function createSelectionController(options) {
200
219
  // a selection — N1 already declines auto-scroll-while-dragging. The notch
201
220
  // then scrolls normally, because the wheel router is a separate subscriber
202
221
  // on the same channel.
203
- if (dragging)
204
- clear();
222
+ clear();
205
223
  return;
206
224
  }
207
225
  if (event.kind === 'press') {
@@ -213,6 +231,7 @@ export function createSelectionController(options) {
213
231
  return;
214
232
  }
215
233
  const cell = cellOf(event);
234
+ settled = false;
216
235
  sel = { anchor: cell, focus: cell };
217
236
  pendingFocus = null;
218
237
  clearFlushTimer();
@@ -248,16 +267,35 @@ export function createSelectionController(options) {
248
267
  finishSelection();
249
268
  };
250
269
  const unsubscribe = options.source.subscribe(onMouse);
270
+ const selectedCellsChanged = (lines) => {
271
+ if (!settled || !sel)
272
+ return false;
273
+ const normal = normalize(sel);
274
+ for (let row = normal.start.row; row <= normal.end.row; row += 1) {
275
+ const span = rowSpan(normal, row);
276
+ if (!span)
277
+ continue;
278
+ const before = sliceColumns(stripAnsi(mirror.raw[row] ?? ''), span.from, span.to);
279
+ const after = sliceColumns(stripAnsi(lines[row] ?? ''), span.from, span.to);
280
+ if (before !== after)
281
+ return true;
282
+ }
283
+ return false;
284
+ };
251
285
  return {
252
286
  decorate(lines) {
253
- mirror.set(lines);
254
- if (painting || sel === null)
255
- return lines;
256
- const normal = normalize(sel);
257
- if (isEmpty(normal))
287
+ if (painting || disposed)
258
288
  return lines;
259
289
  painting = true;
260
290
  try {
291
+ if (selectedCellsChanged(lines))
292
+ clearState();
293
+ mirror.set(lines);
294
+ if (sel === null)
295
+ return lines;
296
+ const normal = normalize(sel);
297
+ if (isEmpty(normal))
298
+ return lines;
261
299
  const open = selectionOpen(options.theme(), options.caps);
262
300
  const cols = Math.max(1, options.cols());
263
301
  const out = lines.slice();
@@ -317,11 +355,11 @@ export function createSelectionController(options) {
317
355
  dispose() {
318
356
  if (disposed)
319
357
  return;
320
- disposed = true;
321
358
  // 4.2.3: a pending selection holds the viewport; teardown must let go
322
359
  // of it explicitly, exactly like `clear()` does.
323
360
  if (holdActive)
324
361
  emitHold(false);
362
+ disposed = true;
325
363
  unsubscribe();
326
364
  clearFlushTimer();
327
365
  clearWatchdog();
@@ -73,6 +73,8 @@ function serviceTextGlyph(status, exitCode, glyphs) {
73
73
  }
74
74
  function renderEntry(entry, glyphs) {
75
75
  switch (entry.kind) {
76
+ case 'queued':
77
+ return block('Queued but never sent:', entry.text);
76
78
  case 'user':
77
79
  return block(glyphs.user, entry.text);
78
80
  case 'assistant': {
@@ -211,20 +213,26 @@ export function renderTranscriptText(entries, opts) {
211
213
  lines.push(`${g.ellipsis} ${dropped} earlier ${dropped === 1 ? 'entry' : 'entries'} dropped by ` +
212
214
  `transcriptRetain ${g.midDot} raise it or /save sooner`);
213
215
  }
214
- if (entries.length > max && max > 1) {
215
- const head = Math.ceil(max / 2);
216
- const tail = max - head;
217
- const omitted = entries.length - max;
218
- for (const entry of entries.slice(0, head))
219
- lines.push(...renderEntry(entry, g));
220
- lines.push(`${g.ellipsis} ${omitted} entries omitted ${g.midDot} use /save before exiting`);
221
- for (const entry of entries.slice(entries.length - tail)) {
216
+ const historyCount = entries.filter((entry) => entry.kind !== 'queued').length;
217
+ const omitted = max > 1 ? Math.max(0, historyCount - max) : 0;
218
+ const head = Math.ceil(max / 2);
219
+ const tailStart = historyCount - (max - head);
220
+ let historyIndex = 0;
221
+ let reported = false;
222
+ for (const entry of entries) {
223
+ if (entry.kind === 'queued') {
222
224
  lines.push(...renderEntry(entry, g));
225
+ continue;
223
226
  }
224
- }
225
- else {
226
- for (const entry of entries)
227
- lines.push(...renderEntry(entry, g));
227
+ const index = historyIndex++;
228
+ if (omitted > 0 && index >= head && index < tailStart) {
229
+ if (!reported) {
230
+ lines.push(`${g.ellipsis} ${omitted} entries omitted ${g.midDot} use /save before exiting`);
231
+ reported = true;
232
+ }
233
+ continue;
234
+ }
235
+ lines.push(...renderEntry(entry, g));
228
236
  }
229
237
  return `${lines.join('\n')}\n`;
230
238
  }
@@ -106,7 +106,8 @@ export function useWheelRouting(options) {
106
106
  if (overlay) {
107
107
  // Modes A only. `model` / `confirm` / `question` own their own keys and
108
108
  // scrolling them would leave an inconsistent cursor (R-11).
109
- const controlled = overlay === 'help' || overlay === 'settings' || overlay === 'plan';
109
+ const controlled = overlay === 'help' || overlay === 'settings'
110
+ || overlay === 'plan' || overlay === 'queue';
110
111
  if (!controlled)
111
112
  return;
112
113
  // D-3: the row is not consulted here either. Behind an overlay the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aragon-agent/cli",
3
- "version": "0.6.11",
3
+ "version": "0.6.13",
4
4
  "description": "AragonAgent CLI — a Claude-Code / Codex-style interactive terminal UI (TUI) on top of the @aragon-agent/core engine. Installable and runnable via npm / npx.",
5
5
  "license": "MIT",
6
6
  "author": "AragonAgent contributors",
@@ -56,7 +56,7 @@
56
56
  "prepublishOnly": "npm run build"
57
57
  },
58
58
  "dependencies": {
59
- "@aragon-agent/core": "^0.2.23",
59
+ "@aragon-agent/core": "^0.2.25",
60
60
  "chalk": "^5.6.2",
61
61
  "cli-highlight": "^2.0.0",
62
62
  "commander": "^12.1.0",