@aragon-agent/cli 0.6.9 → 0.6.10
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/README.md +53 -9
- package/dist/agent/reducer.d.ts +24 -0
- package/dist/agent/reducer.js +41 -1
- package/dist/cli.js +5 -6
- package/dist/commands/builtins.d.ts +2 -1
- package/dist/commands/builtins.js +47 -2
- package/dist/input/enter-sequences.d.ts +63 -0
- package/dist/input/enter-sequences.js +151 -0
- package/dist/input/limits.d.ts +11 -0
- package/dist/input/limits.js +11 -0
- package/dist/input/stdin-filter.js +19 -1
- package/dist/session/persist.js +20 -0
- package/dist/ui/App.js +29 -2
- package/dist/ui/Composer.d.ts +1 -1
- package/dist/ui/Composer.js +4 -1
- package/dist/ui/PromptInput.js +34 -2
- package/dist/ui/Transcript.js +6 -0
- package/dist/ui/enter-frames.d.ts +63 -0
- package/dist/ui/enter-frames.js +136 -0
- package/dist/ui/entries/QueuedEntry.d.ts +27 -0
- package/dist/ui/entries/QueuedEntry.js +30 -0
- package/dist/ui/glyphs.d.ts +9 -0
- package/dist/ui/glyphs.js +2 -0
- package/dist/ui/overlays/HelpOverlay.js +3 -2
- package/dist/ui/overlays/PlanReviewOverlay.js +5 -1
- package/dist/ui/overlays/QuestionOverlay.js +7 -2
- package/dist/ui/overlays/SettingsScreen.js +8 -1
- package/dist/ui/selection/selection-controller.d.ts +23 -7
- package/dist/ui/selection/selection-controller.js +68 -16
- package/dist/ui/use-startup-notices.d.ts +5 -1
- package/dist/ui/use-startup-notices.js +7 -3
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The selection controller (tui-selection-and-scroll-follow §4.4). NON-REACT: it
|
|
3
|
-
* owns the mouse lifecycle, the 16 ms drag coalescer, the `decorate` hook and
|
|
4
|
-
*
|
|
5
|
-
* `App` registers on mount.
|
|
3
|
+
* owns the mouse lifecycle, the 16 ms drag coalescer, the `decorate` hook and
|
|
4
|
+
* the released-selection state Ctrl+C consumes, and it reaches the React tree
|
|
5
|
+
* only through the callbacks `App` registers on mount.
|
|
6
6
|
*
|
|
7
7
|
* WHY IT IS NOT A COMPONENT (D-6). A React re-render per motion report goes
|
|
8
8
|
* through the render governor and the whole component tree; the frame pipeline
|
|
@@ -57,6 +57,10 @@ export function createSelectionController(options) {
|
|
|
57
57
|
let enabled = true;
|
|
58
58
|
let sel = null;
|
|
59
59
|
let dragging = false;
|
|
60
|
+
/** A released, non-empty selection is waiting for Ctrl+C (4.2.1). */
|
|
61
|
+
let settled = false;
|
|
62
|
+
/** Mirror of the last `hold` emitted, so exits can be conditional. */
|
|
63
|
+
let holdActive = false;
|
|
60
64
|
let pendingFocus = null;
|
|
61
65
|
let flushTimer = null;
|
|
62
66
|
let holdWatchdog = null;
|
|
@@ -64,6 +68,7 @@ export function createSelectionController(options) {
|
|
|
64
68
|
/** Guards `decorate` against being re-entered from inside a repaint. */
|
|
65
69
|
let painting = false;
|
|
66
70
|
const emitHold = (hold) => {
|
|
71
|
+
holdActive = hold;
|
|
67
72
|
for (const listener of [...holdListeners])
|
|
68
73
|
listener(hold);
|
|
69
74
|
};
|
|
@@ -121,15 +126,18 @@ export function createSelectionController(options) {
|
|
|
121
126
|
// Nothing to undo: no timers, no repaint, no redraw. This is what keeps
|
|
122
127
|
// `onInvalidate` — which fires on every resize and every foreign write —
|
|
123
128
|
// free for a session that has never selected anything.
|
|
124
|
-
if (sel === null && !dragging && pendingFocus === null)
|
|
129
|
+
if (sel === null && !dragging && pendingFocus === null && !settled)
|
|
125
130
|
return;
|
|
126
|
-
const wasDragging = dragging;
|
|
127
131
|
sel = null;
|
|
128
132
|
dragging = false;
|
|
133
|
+
settled = false;
|
|
129
134
|
pendingFocus = null;
|
|
130
135
|
clearFlushTimer();
|
|
131
136
|
clearWatchdog();
|
|
132
|
-
|
|
137
|
+
// `holdActive`, not `wasDragging`: since tui-shift-enter-copy-queue a
|
|
138
|
+
// RELEASED selection also holds the viewport (4.2.3), so this is the
|
|
139
|
+
// exit for two states, not one.
|
|
140
|
+
if (holdActive)
|
|
133
141
|
emitHold(false);
|
|
134
142
|
paint(false);
|
|
135
143
|
};
|
|
@@ -150,26 +158,38 @@ export function createSelectionController(options) {
|
|
|
150
158
|
paint(true);
|
|
151
159
|
};
|
|
152
160
|
const finishSelection = () => {
|
|
153
|
-
if (!sel)
|
|
161
|
+
if (!sel) {
|
|
162
|
+
emitHold(false);
|
|
154
163
|
return;
|
|
164
|
+
}
|
|
155
165
|
const normal = normalize(sel);
|
|
156
166
|
if (isEmpty(normal)) {
|
|
157
|
-
// A plain click. It must never leave a one-cell highlight behind, and
|
|
158
|
-
// must never clobber the clipboard.
|
|
167
|
+
// A plain click. It must never leave a one-cell highlight behind, and
|
|
168
|
+
// it must never clobber the clipboard.
|
|
159
169
|
sel = null;
|
|
170
|
+
settled = false;
|
|
171
|
+
emitHold(false);
|
|
160
172
|
paint(false);
|
|
161
173
|
return;
|
|
162
174
|
}
|
|
163
|
-
|
|
164
|
-
|
|
175
|
+
if (selectedText(mirror.plain, normal).length === 0) {
|
|
176
|
+
// Geometry without content (blank cells): nothing honest to promise a
|
|
177
|
+
// later Ctrl+C, so this is the same no-op a click is.
|
|
165
178
|
sel = null;
|
|
179
|
+
settled = false;
|
|
180
|
+
emitHold(false);
|
|
166
181
|
paint(false);
|
|
167
182
|
return;
|
|
168
183
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
//
|
|
172
|
-
//
|
|
184
|
+
// RELEASED AND NON-EMPTY: the highlight STAYS and so does the hold
|
|
185
|
+
// (4.2.1 / 4.2.3). The highlight is the promise of what Ctrl+C will
|
|
186
|
+
// copy -- not a receipt for a copy that already happened -- and the
|
|
187
|
+
// hold keeps the rows under it frozen until that promise resolves,
|
|
188
|
+
// which is what lets "what you see is what you get" survive a
|
|
189
|
+
// streaming run. The watchdog is NOT re-armed: the release already
|
|
190
|
+
// happened, and the frozen state has explicit exits (Ctrl+C, any other
|
|
191
|
+
// key, resize, overlay, /mouse off).
|
|
192
|
+
settled = true;
|
|
173
193
|
paint(true);
|
|
174
194
|
};
|
|
175
195
|
const onMouse = (event) => {
|
|
@@ -222,7 +242,9 @@ export function createSelectionController(options) {
|
|
|
222
242
|
clearFlushTimer();
|
|
223
243
|
clearWatchdog();
|
|
224
244
|
dragging = false;
|
|
225
|
-
|
|
245
|
+
// `finishSelection` decides the hold: a non-empty release KEEPS it
|
|
246
|
+
// (4.2.3) so the pending selection cannot be pushed off screen; every
|
|
247
|
+
// empty path releases it there.
|
|
226
248
|
finishSelection();
|
|
227
249
|
};
|
|
228
250
|
const unsubscribe = options.source.subscribe(onMouse);
|
|
@@ -258,6 +280,32 @@ export function createSelectionController(options) {
|
|
|
258
280
|
holdListeners.add(listener);
|
|
259
281
|
return () => holdListeners.delete(listener);
|
|
260
282
|
},
|
|
283
|
+
hasPendingSelection() {
|
|
284
|
+
return settled && sel !== null;
|
|
285
|
+
},
|
|
286
|
+
takeSelection() {
|
|
287
|
+
if (!settled || sel === null)
|
|
288
|
+
return null;
|
|
289
|
+
const normal = normalize(sel);
|
|
290
|
+
const text = selectedText(mirror.plain, normal);
|
|
291
|
+
// CONSUMED BEFORE THE CALLER COPIES (4.3 / R7). The copy writes OSC
|
|
292
|
+
// 52 through `writeForeign`; the differ treats that as a foreign
|
|
293
|
+
// write and invalidates, and `onInvalidate` clears this controller on
|
|
294
|
+
// the next macrotask. Clearing first makes that callback a no-op;
|
|
295
|
+
// copying first would let it erase the held viewport state a tick
|
|
296
|
+
// after the copy -- the "copy flashes the screen" regression.
|
|
297
|
+
sel = null;
|
|
298
|
+
settled = false;
|
|
299
|
+
pendingFocus = null;
|
|
300
|
+
clearFlushTimer();
|
|
301
|
+
clearWatchdog();
|
|
302
|
+
if (holdActive)
|
|
303
|
+
emitHold(false);
|
|
304
|
+
paint(false);
|
|
305
|
+
if (text.length === 0)
|
|
306
|
+
return null;
|
|
307
|
+
return { text, lines: text.split('\n').length };
|
|
308
|
+
},
|
|
261
309
|
clear,
|
|
262
310
|
setEnabled(next) {
|
|
263
311
|
if (enabled === next)
|
|
@@ -270,6 +318,10 @@ export function createSelectionController(options) {
|
|
|
270
318
|
if (disposed)
|
|
271
319
|
return;
|
|
272
320
|
disposed = true;
|
|
321
|
+
// 4.2.3: a pending selection holds the viewport; teardown must let go
|
|
322
|
+
// of it explicitly, exactly like `clear()` does.
|
|
323
|
+
if (holdActive)
|
|
324
|
+
emitHold(false);
|
|
273
325
|
unsubscribe();
|
|
274
326
|
clearFlushTimer();
|
|
275
327
|
clearWatchdog();
|
|
@@ -22,8 +22,12 @@ import type { ViewAction } from '../agent/reducer.js';
|
|
|
22
22
|
*
|
|
23
23
|
* `1` = the first text that names DRAG-SELECT and `/mouse`. `0` = the 0.6.2 text
|
|
24
24
|
* that taught the Shift bypass, recorded back when this was a boolean.
|
|
25
|
+
* `2` = the Ctrl+C-to-copy text (tui-shift-enter-copy-queue 4.4): releasing
|
|
26
|
+
* no longer copies, and every user who learned the old gesture -- which is
|
|
27
|
+
* every user who has a version recorded at all -- has to be told the new
|
|
28
|
+
* one, once.
|
|
25
29
|
*/
|
|
26
|
-
export declare const MOUSE_NOTICE_VERSION =
|
|
30
|
+
export declare const MOUSE_NOTICE_VERSION = 2;
|
|
27
31
|
/**
|
|
28
32
|
* The revision of the text below that a user must have seen for this notice to
|
|
29
33
|
* stay quiet (`state.json::vtInputNoticeVersion`, `0` when absent).
|
|
@@ -26,8 +26,12 @@ import { getLogger } from '../logging/logger.js';
|
|
|
26
26
|
*
|
|
27
27
|
* `1` = the first text that names DRAG-SELECT and `/mouse`. `0` = the 0.6.2 text
|
|
28
28
|
* that taught the Shift bypass, recorded back when this was a boolean.
|
|
29
|
+
* `2` = the Ctrl+C-to-copy text (tui-shift-enter-copy-queue 4.4): releasing
|
|
30
|
+
* no longer copies, and every user who learned the old gesture -- which is
|
|
31
|
+
* every user who has a version recorded at all -- has to be told the new
|
|
32
|
+
* one, once.
|
|
29
33
|
*/
|
|
30
|
-
export const MOUSE_NOTICE_VERSION =
|
|
34
|
+
export const MOUSE_NOTICE_VERSION = 2;
|
|
31
35
|
/**
|
|
32
36
|
* The one-shot mouse notice (tui-selection-and-scroll-follow §5.2 row 29).
|
|
33
37
|
*
|
|
@@ -47,8 +51,8 @@ function mouseNoticeText(selectEnabled) {
|
|
|
47
51
|
return ('Mouse wheel scrolls the transcript. Drag-select is off (mouseSelect); ' +
|
|
48
52
|
'/mouse off hands the mouse back to your terminal for this session.');
|
|
49
53
|
}
|
|
50
|
-
return ('Mouse wheel scrolls the transcript
|
|
51
|
-
'
|
|
54
|
+
return ('Mouse wheel scrolls the transcript; drag to select, then Ctrl+C to copy. ' +
|
|
55
|
+
'/mouse off hands the mouse back to your terminal for this session.');
|
|
52
56
|
}
|
|
53
57
|
/**
|
|
54
58
|
* The §5.1 notice (tui-render-performance). Shown once per run, and only when
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aragon-agent/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.10",
|
|
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.
|
|
59
|
+
"@aragon-agent/core": "^0.2.22",
|
|
60
60
|
"chalk": "^5.6.2",
|
|
61
61
|
"cli-highlight": "^2.0.0",
|
|
62
62
|
"commander": "^12.1.0",
|