@tiens.nguyen/gonext-cli 1.0.372 → 1.0.373
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/gonext-repl.mjs +53 -10
- package/package.json +1 -1
package/gonext-repl.mjs
CHANGED
|
@@ -362,6 +362,7 @@ const COMMANDS = [
|
|
|
362
362
|
{ name: "/server", desc: "pick a deployment server (host/user) for this session" },
|
|
363
363
|
{ name: "/manual-edit", aliases: ["/revert"], usage: "/manual-edit [runId]", desc: "undo the agent's file edits so you can edit them yourself (latest run)" },
|
|
364
364
|
{ name: "/reset", aliases: ["/new"], desc: "forget this folder's saved conversation and start fresh" },
|
|
365
|
+
{ name: "/hover", desc: "toggle mouse hover/click on the thinking line (costs scrolling while it runs)" },
|
|
365
366
|
{ name: "/output-token", desc: "show the agent code-model OUTPUT-token total for this workspace" },
|
|
366
367
|
{ name: "/reset-output-token-global", desc: "reset the GLOBAL (you + coding server) output-token total to 0" },
|
|
367
368
|
{ name: "/help", desc: "list these commands" },
|
|
@@ -762,6 +763,10 @@ if (process.stdin.isTTY) {
|
|
|
762
763
|
return;
|
|
763
764
|
}
|
|
764
765
|
if (following) {
|
|
766
|
+
// Ctrl+T expands/collapses the model's current Thought — the keyboard equivalent of the
|
|
767
|
+
// hover-click, so the fuller thought stays reachable with the mouse capture off (the
|
|
768
|
+
// capture is what would eat the scroll wheel; see hoverMouse).
|
|
769
|
+
if (key && key.ctrl && key.name === "t" && toggleActiveThought) toggleActiveThought();
|
|
765
770
|
rl.line = "";
|
|
766
771
|
rl.cursor = 0;
|
|
767
772
|
rl.historyIndex = -1;
|
|
@@ -810,18 +815,24 @@ rl.on("close", () => {
|
|
|
810
815
|
w(null);
|
|
811
816
|
}
|
|
812
817
|
});
|
|
813
|
-
// Mouse hover+click on the thinking line (task #96):
|
|
814
|
-
//
|
|
815
|
-
//
|
|
816
|
-
//
|
|
817
|
-
//
|
|
818
|
-
//
|
|
819
|
-
//
|
|
818
|
+
// Mouse hover+click on the thinking line (task #96): turns ON xterm ANY-MOTION tracking for
|
|
819
|
+
// the duration of a turn so we can HIGHLIGHT the line as the mouse hovers it AND expand it on
|
|
820
|
+
// click. ?1003 = report every button press/release AND all mouse MOTION (needed for hover with
|
|
821
|
+
// no button held); ?1006 = SGR extended coords (no 223-col cap). We disable ?1000/?1002 too on
|
|
822
|
+
// teardown in case a terminal had them latched.
|
|
823
|
+
//
|
|
824
|
+
// OFF BY DEFAULT, and it has to be: with ANY mouse reporting enabled the terminal hands us the
|
|
825
|
+
// WHEEL events (SGR button 64/65) instead of scrolling its own scrollback, so the user cannot
|
|
826
|
+
// scroll while a turn runs — and no tracking mode reports motion without also grabbing the
|
|
827
|
+
// wheel, so hover and scrolling are mutually exclusive. Scrolling wins by default (it also
|
|
828
|
+
// gives back native drag-to-select); `/hover` opts back into the mouse for a session, and
|
|
829
|
+
// Ctrl+T expands the thought from the keyboard either way.
|
|
830
|
+
let hoverMouse = false;
|
|
820
831
|
const MOUSE_ON = "\x1b[?1003h\x1b[?1006h";
|
|
821
832
|
const MOUSE_OFF = "\x1b[?1003l\x1b[?1002l\x1b[?1000l\x1b[?1006l";
|
|
822
833
|
let _mouseEnabled = false;
|
|
823
834
|
const enableMouse = () => {
|
|
824
|
-
if (_mouseEnabled || !process.stdin.isTTY) return;
|
|
835
|
+
if (!hoverMouse || _mouseEnabled || !process.stdin.isTTY) return;
|
|
825
836
|
process.stdout.write(MOUSE_ON);
|
|
826
837
|
_mouseEnabled = true;
|
|
827
838
|
};
|
|
@@ -1399,6 +1410,10 @@ let approvalResolve = null;
|
|
|
1399
1410
|
// first — otherwise the 120ms ticker keeps redrawing that block on top of the picker and
|
|
1400
1411
|
// its relative-cursor math lands on the wrong rows (duplicated/interleaved options).
|
|
1401
1412
|
let clearActiveStatus = null;
|
|
1413
|
+
// The active turn's thought expand/collapse (its local toggle), or null between turns — lets
|
|
1414
|
+
// Ctrl+T reveal the full Thought from the KEYBOARD, so the feature doesn't depend on the mouse
|
|
1415
|
+
// capture that would block scrolling (see hoverMouse).
|
|
1416
|
+
let toggleActiveThought = null;
|
|
1402
1417
|
function drawApprovalOptions(redraw) {
|
|
1403
1418
|
// Two option lines, redrawn in place. On redraw the cursor sits one row below "No";
|
|
1404
1419
|
// step up 2 rows, clear+rewrite both, landing back where we started.
|
|
@@ -2045,7 +2060,9 @@ async function runAgentTurn(history) {
|
|
|
2045
2060
|
clearStatus();
|
|
2046
2061
|
// Right after clearing, the cursor sits at the status block's TOP-LEFT = the thought line's
|
|
2047
2062
|
// row. Probe for it (throttled) so hover/click hit-testing is exact wherever the block is.
|
|
2048
|
-
|
|
2063
|
+
// Only worth probing when the mouse is captured — thoughtRow exists for hover/click
|
|
2064
|
+
// hit-testing, and with `/hover` off nothing reads it (and nothing would consume the reply).
|
|
2065
|
+
if (hoverMouse && process.stdin.isTTY && now - lastDsrAt > 400) { lastDsrAt = now; process.stdout.write("\x1b[6n"); }
|
|
2049
2066
|
// Line 1: green ● + green phase/seconds (matches the web's green streaming label), or the
|
|
2050
2067
|
// underlined bright-green hover style when the mouse is over a clickable thought. Then the
|
|
2051
2068
|
// GREY expanded lines (if any), then LAST the SPINNER + playful word + token labels
|
|
@@ -2085,10 +2102,18 @@ async function runAgentTurn(history) {
|
|
|
2085
2102
|
if (row < top || row > top + statusContentLines - 2) return;
|
|
2086
2103
|
// Only meaningful when there IS a fuller thought to reveal; otherwise ignore the click
|
|
2087
2104
|
// so we don't flicker an empty expand.
|
|
2105
|
+
if (!thoughtExpanded && !(fullLiveThought && !runningCmd)) return;
|
|
2106
|
+
toggleThought();
|
|
2107
|
+
};
|
|
2108
|
+
// Same expand/collapse, reachable without the mouse: Ctrl+T while a turn runs (see
|
|
2109
|
+
// toggleActiveThought). Ignored when there's nothing more to reveal, so it never flickers an
|
|
2110
|
+
// empty expansion.
|
|
2111
|
+
const toggleThought = () => {
|
|
2088
2112
|
if (!thoughtExpanded && !(fullLiveThought && !runningCmd)) return;
|
|
2089
2113
|
thoughtExpanded = !thoughtExpanded;
|
|
2090
2114
|
clearStatus(); // next tick (≤120ms) redraws at the new size; keeps cursor math correct
|
|
2091
2115
|
};
|
|
2116
|
+
toggleActiveThought = toggleThought;
|
|
2092
2117
|
const onMouseData = (chunk) => {
|
|
2093
2118
|
if (!following) return;
|
|
2094
2119
|
const s = chunk.toString("latin1");
|
|
@@ -2107,7 +2132,9 @@ async function runAgentTurn(history) {
|
|
|
2107
2132
|
if (isPress && (btn & 0b11) === 0 && (btn & 64) === 0) onStatusClick(row); // left click → expand
|
|
2108
2133
|
}
|
|
2109
2134
|
};
|
|
2110
|
-
|
|
2135
|
+
// Only listen for reports when we're actually capturing the mouse — with `/hover` off there
|
|
2136
|
+
// are none, and no \x1b[6n probe reply to consume either.
|
|
2137
|
+
if (hoverMouse && process.stdin.isTTY) process.stdin.on("data", onMouseData);
|
|
2111
2138
|
enableMouse();
|
|
2112
2139
|
|
|
2113
2140
|
// Called right before any real (bullet/edit-card/answer) content prints: drop the
|
|
@@ -2586,6 +2613,7 @@ async function runAgentTurn(history) {
|
|
|
2586
2613
|
clearInterval(ticker);
|
|
2587
2614
|
clearStatus();
|
|
2588
2615
|
clearActiveStatus = null; // no turn owns the status wiper between turns
|
|
2616
|
+
toggleActiveThought = null; // …nor the Ctrl+T thought toggle
|
|
2589
2617
|
// Task #96: stop mouse-reporting the moment the turn ends (also on cancel/error — this
|
|
2590
2618
|
// finally always runs), and detach the click parser, so the user's shell selection is
|
|
2591
2619
|
// never captured between turns.
|
|
@@ -2831,6 +2859,21 @@ async function main() {
|
|
|
2831
2859
|
printCommands();
|
|
2832
2860
|
continue;
|
|
2833
2861
|
}
|
|
2862
|
+
if (line === "/hover") {
|
|
2863
|
+
// Mouse hover/click on the thinking line (#96) vs. scrolling during a turn: the terminal
|
|
2864
|
+
// only reports wheel events to US when mouse tracking is on, so they're exclusive. Off by
|
|
2865
|
+
// default; this opts in for the session. Ctrl+T expands the thought either way.
|
|
2866
|
+
hoverMouse = !hoverMouse;
|
|
2867
|
+
console.log(
|
|
2868
|
+
(hoverMouse ? green("hover: ON") : dim("hover: OFF")) +
|
|
2869
|
+
dim(
|
|
2870
|
+
hoverMouse
|
|
2871
|
+
? " — mouse hover/click expands the thinking line; scrolling and drag-select are captured while a turn runs.\n"
|
|
2872
|
+
: " — scrolling and drag-select work during a turn; use Ctrl+T to expand the thinking line.\n"
|
|
2873
|
+
)
|
|
2874
|
+
);
|
|
2875
|
+
continue;
|
|
2876
|
+
}
|
|
2834
2877
|
if (line === "/model") {
|
|
2835
2878
|
await chooseModel();
|
|
2836
2879
|
continue;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiens.nguyen/gonext-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.373",
|
|
4
4
|
"description": "GoNext CLI — the gonext terminal plus the local worker that runs agent / OCR / PDF / embedding jobs on your Mac (Ollama / MLX / OpenAI-compatible).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|