@yuaone/cli 0.9.5 → 0.9.6
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.
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* useMouseScroll — enables
|
|
2
|
+
* useMouseScroll — enables mouse wheel scrolling in the TUI.
|
|
3
3
|
*
|
|
4
4
|
* Problem: Ink's useInput doesn't handle mouse events, and enabling mouse
|
|
5
5
|
* tracking causes raw escape sequences to leak into Ink's readline → garbage
|
|
6
6
|
* text in InputBox.
|
|
7
7
|
*
|
|
8
|
-
* Solution: Enable X10 basic mouse protocol (
|
|
9
|
-
* monkey-patch process.stdin.emit to intercept
|
|
10
|
-
* before Ink's readline processes them. Scroll
|
|
8
|
+
* Solution: Enable BOTH X10 basic mouse protocol (1000h) AND SGR extended
|
|
9
|
+
* mouse protocol (1006h), then monkey-patch process.stdin.emit to intercept
|
|
10
|
+
* and strip mouse sequences before Ink's readline processes them. Scroll
|
|
11
|
+
* events are routed to callbacks.
|
|
11
12
|
*
|
|
12
|
-
* X10 protocol: \x1b[M <button> <col> <row> (3 bytes after \x1b[M)
|
|
13
|
-
* Scroll up
|
|
14
|
-
* Scroll down
|
|
13
|
+
* X10 protocol : \x1b[M <button> <col> <row> (3 bytes after \x1b[M)
|
|
14
|
+
* Scroll up : button byte = 96 (64 + 32 offset)
|
|
15
|
+
* Scroll down : button byte = 97 (65 + 32 offset)
|
|
16
|
+
*
|
|
17
|
+
* SGR protocol : \x1b[<button;col;rowM (press) or \x1b[<button;col;rowm (release)
|
|
18
|
+
* Scroll up : button = 64 → \x1b[<64;col;rowM
|
|
19
|
+
* Scroll down : button = 65 → \x1b[<65;col;rowM
|
|
20
|
+
*
|
|
21
|
+
* Modern terminals (iTerm2, kitty, most Linux terminals) use SGR (1006h).
|
|
22
|
+
* Both parsers are kept so legacy terminals using only X10 still work.
|
|
15
23
|
*/
|
|
16
24
|
export declare function useMouseScroll(onScrollUp: () => void, onScrollDown: () => void): void;
|
|
17
25
|
//# sourceMappingURL=useMouseScroll.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMouseScroll.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useMouseScroll.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"useMouseScroll.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/useMouseScroll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAuBH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,IAAI,EACtB,YAAY,EAAE,MAAM,IAAI,GACvB,IAAI,CAoFN"}
|
|
@@ -1,26 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* useMouseScroll — enables
|
|
2
|
+
* useMouseScroll — enables mouse wheel scrolling in the TUI.
|
|
3
3
|
*
|
|
4
4
|
* Problem: Ink's useInput doesn't handle mouse events, and enabling mouse
|
|
5
5
|
* tracking causes raw escape sequences to leak into Ink's readline → garbage
|
|
6
6
|
* text in InputBox.
|
|
7
7
|
*
|
|
8
|
-
* Solution: Enable X10 basic mouse protocol (
|
|
9
|
-
* monkey-patch process.stdin.emit to intercept
|
|
10
|
-
* before Ink's readline processes them. Scroll
|
|
8
|
+
* Solution: Enable BOTH X10 basic mouse protocol (1000h) AND SGR extended
|
|
9
|
+
* mouse protocol (1006h), then monkey-patch process.stdin.emit to intercept
|
|
10
|
+
* and strip mouse sequences before Ink's readline processes them. Scroll
|
|
11
|
+
* events are routed to callbacks.
|
|
11
12
|
*
|
|
12
|
-
* X10 protocol: \x1b[M <button> <col> <row> (3 bytes after \x1b[M)
|
|
13
|
-
* Scroll up
|
|
14
|
-
* Scroll down
|
|
13
|
+
* X10 protocol : \x1b[M <button> <col> <row> (3 bytes after \x1b[M)
|
|
14
|
+
* Scroll up : button byte = 96 (64 + 32 offset)
|
|
15
|
+
* Scroll down : button byte = 97 (65 + 32 offset)
|
|
16
|
+
*
|
|
17
|
+
* SGR protocol : \x1b[<button;col;rowM (press) or \x1b[<button;col;rowm (release)
|
|
18
|
+
* Scroll up : button = 64 → \x1b[<64;col;rowM
|
|
19
|
+
* Scroll down : button = 65 → \x1b[<65;col;rowM
|
|
20
|
+
*
|
|
21
|
+
* Modern terminals (iTerm2, kitty, most Linux terminals) use SGR (1006h).
|
|
22
|
+
* Both parsers are kept so legacy terminals using only X10 still work.
|
|
15
23
|
*/
|
|
16
24
|
import { useEffect, useRef } from "react";
|
|
17
|
-
const MOUSE_ENABLE = "\x1b[?1000h"; // X10
|
|
18
|
-
const MOUSE_DISABLE = "\x1b[?1000l";
|
|
19
|
-
//
|
|
25
|
+
const MOUSE_ENABLE = "\x1b[?1000h\x1b[?1006h"; // X10 + SGR extended mouse tracking
|
|
26
|
+
const MOUSE_DISABLE = "\x1b[?1006l\x1b[?1000l"; // disable SGR first, then X10
|
|
27
|
+
// X10: button codes after the 32-offset encoding
|
|
20
28
|
const SCROLL_UP_BTN = 96; // button 64 + 32
|
|
21
29
|
const SCROLL_DOWN_BTN = 97; // button 65 + 32
|
|
22
|
-
//
|
|
23
|
-
const
|
|
30
|
+
// X10: matches a complete X10 mouse sequence: ESC [ M + 3 bytes
|
|
31
|
+
const X10_MOUSE_PATTERN = /\x1b\[M[\s\S]{3}/g;
|
|
32
|
+
// SGR: matches \x1b[<button;col;rowM or \x1b[<button;col;rowm
|
|
33
|
+
const SGR_MOUSE_PATTERN = /\x1b\[<(\d+);(\d+);(\d+)([Mm])/g;
|
|
34
|
+
// SGR scroll button codes (no offset applied — raw values)
|
|
35
|
+
const SGR_SCROLL_UP = 64;
|
|
36
|
+
const SGR_SCROLL_DOWN = 65;
|
|
24
37
|
export function useMouseScroll(onScrollUp, onScrollDown) {
|
|
25
38
|
// Keep callback refs stable so the effect only runs once
|
|
26
39
|
const upRef = useRef(onScrollUp);
|
|
@@ -43,10 +56,23 @@ export function useMouseScroll(onScrollUp, onScrollDown) {
|
|
|
43
56
|
: typeof raw === "string"
|
|
44
57
|
? raw
|
|
45
58
|
: "";
|
|
59
|
+
let ups = 0;
|
|
60
|
+
let downs = 0;
|
|
61
|
+
let stripped = str;
|
|
62
|
+
// --- SGR mouse protocol parsing (\x1b[<...) ---
|
|
63
|
+
if (str.includes("\x1b[<")) {
|
|
64
|
+
stripped = stripped.replace(SGR_MOUSE_PATTERN, (_match, btnStr) => {
|
|
65
|
+
const btn = parseInt(btnStr, 10);
|
|
66
|
+
if (btn === SGR_SCROLL_UP)
|
|
67
|
+
ups++;
|
|
68
|
+
else if (btn === SGR_SCROLL_DOWN)
|
|
69
|
+
downs++;
|
|
70
|
+
return ""; // remove from stream
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// --- X10 mouse protocol parsing (\x1b[M...) ---
|
|
46
74
|
if (str.includes("\x1b[M")) {
|
|
47
|
-
|
|
48
|
-
let downs = 0;
|
|
49
|
-
const stripped = str.replace(MOUSE_PATTERN, (match) => {
|
|
75
|
+
stripped = stripped.replace(X10_MOUSE_PATTERN, (match) => {
|
|
50
76
|
// byte index 3 = button byte
|
|
51
77
|
const btn = match.charCodeAt(3);
|
|
52
78
|
if (btn === SCROLL_UP_BTN)
|
|
@@ -55,6 +81,9 @@ export function useMouseScroll(onScrollUp, onScrollDown) {
|
|
|
55
81
|
downs++;
|
|
56
82
|
return ""; // remove from stream
|
|
57
83
|
});
|
|
84
|
+
}
|
|
85
|
+
// If we consumed any mouse sequences, handle callbacks and routing
|
|
86
|
+
if (ups > 0 || downs > 0 || stripped !== str) {
|
|
58
87
|
// Fire scroll callbacks
|
|
59
88
|
for (let i = 0; i < ups; i++)
|
|
60
89
|
upRef.current();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMouseScroll.js","sourceRoot":"","sources":["../../../src/tui/hooks/useMouseScroll.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"useMouseScroll.js","sourceRoot":"","sources":["../../../src/tui/hooks/useMouseScroll.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuaone/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.6",
|
|
4
4
|
"description": "YUAN — Autonomous Coding Agent CLI",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"type": "module",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"string-width": "7.2.0",
|
|
49
49
|
"strip-ansi": "7.1.0",
|
|
50
50
|
"wrap-ansi": "9.0.0",
|
|
51
|
-
"@yuaone/core": "0.9.
|
|
51
|
+
"@yuaone/core": "0.9.4",
|
|
52
52
|
"@yuaone/tools": "0.9.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|