termbeam 1.24.9 → 1.24.11

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.24.11] - 2026-07-08
4
+
5
+ - fix(cli): handle split and coalesced key input in choose() arrow navigation (@dorlugasigal)
6
+
7
+ ## [1.24.10] - 2026-07-07
8
+
9
+ - feat(ci): autonomous Dependabot auto-fix and auto-merge workflows (#263) (@dorlugasigal)
10
+ - fix(ci): allow Dependabot to activate the autofix agent (roles: all) (#266) (@dorlugasigal)
11
+ - chore(ci): bump the all-actions group across 1 directory with 5 updates (#264) (@dependabot[bot])
12
+ - chore(deps): bump the all-npm group across 1 directory with 7 updates (#260) (@dependabot[bot])
13
+ - chore(deps): bump node from `aa27a5f` to `a1d9d67` in the all-docker group (#257) (@dependabot[bot])
14
+ - feat(ci): auto patch-release after Dependabot merges (#268) (@dorlugasigal)
15
+
3
16
  ## [1.24.9] - 2026-06-25
4
17
 
5
18
  - chore(deps): consolidate #242 #243 #244 + fix CodeQL alert + npm audit fix (#245) (@dorlugasigal)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termbeam",
3
- "version": "1.24.9",
3
+ "version": "1.24.11",
4
4
  "description": "Beam your terminal to any device — mobile-optimized web terminal with multi-session support",
5
5
  "main": "src/server/index.js",
6
6
  "bin": {
@@ -74,24 +74,60 @@ function choose(rl, question, choices, defaultIndex = 0) {
74
74
  }
75
75
  process.stdin.resume();
76
76
 
77
+ // Bytes arrive as a raw stream: a single keypress may be split across
78
+ // multiple 'data' events, and several keypresses may be coalesced into one
79
+ // (common when keys are pressed quickly). Buffer the stream and consume one
80
+ // recognized token at a time so navigation never silently drops keys.
81
+ let pending = Buffer.alloc(0);
82
+
83
+ function moveUp() {
84
+ selected = (selected - 1 + items.length) % items.length;
85
+ render(true);
86
+ }
87
+ function moveDown() {
88
+ selected = (selected + 1) % items.length;
89
+ render(true);
90
+ }
91
+
77
92
  function onKey(buf) {
78
- const key = buf.toString();
79
-
80
- if (key === '\x1b[A' || key === 'k') {
81
- selected = (selected - 1 + items.length) % items.length;
82
- render(true);
83
- } else if (key === '\x1b[B' || key === 'j') {
84
- selected = (selected + 1) % items.length;
85
- render(true);
86
- } else if (key === '\r' || key === '\n') {
87
- cleanup();
88
- process.stdout.write('\r\x1b[K\n');
89
- console.log(dim(` Selected: ${items[selected].label}`));
90
- resolve({ index: selected, value: items[selected].label });
91
- } else if (key === '\x03') {
92
- cleanup();
93
- process.stdout.write('\x1b[?1049l');
94
- process.exit(0);
93
+ pending = pending.length ? Buffer.concat([pending, buf]) : buf;
94
+
95
+ while (pending.length > 0) {
96
+ const b = pending[0];
97
+
98
+ if (b === 0x1b) {
99
+ // Escape sequence need at least ESC '[' <code> to interpret.
100
+ if (pending.length < 2) return; // wait for more bytes
101
+ if (pending[1] === 0x5b /* [ */) {
102
+ if (pending.length < 3) return; // wait for the final byte
103
+ const code = pending[2];
104
+ if (code === 0x41 /* A */) moveUp();
105
+ else if (code === 0x42 /* B */) moveDown();
106
+ // Ignore other CSI sequences (left/right/home/etc.)
107
+ pending = pending.subarray(3);
108
+ } else {
109
+ // Lone ESC or unsupported sequence — drop the ESC and continue.
110
+ pending = pending.subarray(1);
111
+ }
112
+ continue;
113
+ }
114
+
115
+ if (b === 0x0d /* \r */ || b === 0x0a /* \n */) {
116
+ cleanup();
117
+ process.stdout.write('\r\x1b[K\n');
118
+ console.log(dim(` Selected: ${items[selected].label}`));
119
+ resolve({ index: selected, value: items[selected].label });
120
+ return;
121
+ }
122
+ if (b === 0x03 /* Ctrl-C */) {
123
+ cleanup();
124
+ process.stdout.write('\x1b[?1049l');
125
+ process.exit(0);
126
+ }
127
+ if (b === 0x6b /* k */) moveUp();
128
+ else if (b === 0x6a /* j */) moveDown();
129
+ // Any other byte is ignored.
130
+ pending = pending.subarray(1);
95
131
  }
96
132
  }
97
133