dsh-ssh-tui 0.5.9 → 0.6.0

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 (56) hide show
  1. package/README.en.md +28 -5
  2. package/README.md +76 -6
  3. package/lib/attach.js +156 -0
  4. package/lib/attach.js.map +1 -0
  5. package/lib/commands.js +73 -0
  6. package/lib/commands.js.map +1 -0
  7. package/lib/diag.js +292 -0
  8. package/lib/diag.js.map +1 -0
  9. package/lib/dialogs.js +82 -0
  10. package/lib/dialogs.js.map +1 -0
  11. package/lib/display-sock.js +304 -86
  12. package/lib/display-sock.js.map +1 -1
  13. package/lib/dsh-compat.js +25 -4
  14. package/lib/dsh-compat.js.map +1 -1
  15. package/lib/i18n/en.js +55 -0
  16. package/lib/i18n/en.js.map +1 -1
  17. package/lib/i18n/index.js +2 -0
  18. package/lib/i18n/index.js.map +1 -1
  19. package/lib/i18n/zh.js +55 -0
  20. package/lib/i18n/zh.js.map +1 -1
  21. package/lib/index.js +75 -73
  22. package/lib/index.js.map +1 -1
  23. package/lib/paint.js +20 -38
  24. package/lib/paint.js.map +1 -1
  25. package/lib/picker.js +152 -37
  26. package/lib/picker.js.map +1 -1
  27. package/lib/rows.js +120 -0
  28. package/lib/rows.js.map +1 -0
  29. package/lib/session-index.js +4 -1
  30. package/lib/session-index.js.map +1 -1
  31. package/lib/session-list.js +372 -167
  32. package/lib/session-list.js.map +1 -1
  33. package/lib/session-lock.js +20 -9
  34. package/lib/session-lock.js.map +1 -1
  35. package/lib/stats.js +136 -0
  36. package/lib/stats.js.map +1 -0
  37. package/lib/terminal-input.js +470 -0
  38. package/lib/terminal-input.js.map +1 -0
  39. package/lib/tui.js +257 -311
  40. package/lib/tui.js.map +1 -1
  41. package/lib/types/attach.d.ts +106 -0
  42. package/lib/types/commands.d.ts +103 -0
  43. package/lib/types/diag.d.ts +78 -0
  44. package/lib/types/dialogs.d.ts +79 -0
  45. package/lib/types/display-sock.d.ts +59 -3
  46. package/lib/types/dsh-compat.d.ts +7 -0
  47. package/lib/types/i18n/index.d.ts +4 -0
  48. package/lib/types/index.d.ts +8 -4
  49. package/lib/types/paint.d.ts +6 -3
  50. package/lib/types/picker.d.ts +27 -7
  51. package/lib/types/rows.d.ts +69 -0
  52. package/lib/types/session-list.d.ts +43 -3
  53. package/lib/types/stats.d.ts +98 -0
  54. package/lib/types/terminal-input.d.ts +164 -0
  55. package/lib/types/tui.d.ts +33 -8
  56. package/package.json +11 -5
@@ -0,0 +1,470 @@
1
+ /**
2
+ * Terminal input hygiene for the display relay.
3
+ *
4
+ * The relay measures the SSH round-trip with a Device Status Report (`CSI 6n`)
5
+ * and the terminal answers with a cursor position report (`CSI row;col R`).
6
+ * That answer arrives on stdin, where it is indistinguishable from typing: if
7
+ * it lands after the probe's window closed — the terminal was still busy with
8
+ * a repaint, the link queued it behind a burst, or an earlier launcher asked
9
+ * and died before reading it — it used to be forwarded to the Host and painted
10
+ * into the prompt as `[17;1R`. An ESC whose tail arrived in a later read
11
+ * cancelled whatever dialog was open, and while two launchers fought over one
12
+ * session the TTY spent half its time in cooked mode, so the replies in flight
13
+ * were *echoed* as `^[[17;1R` lines on top of the TUI.
14
+ *
15
+ * The same in-flight replies corrupt the measurement itself: the probe that
16
+ * reads a previous request's answer reports ~2 ms, and the answer to its own
17
+ * request is still on the wire (it becomes the next garbage the prompt shows).
18
+ * A DSR request can also be queued behind a full-screen repaint, which is how
19
+ * a 50 ms SSH link reported 1900 ms.
20
+ *
21
+ * Two things keep both under control:
22
+ * - `TerminalInputFilter` removes replies from the byte stream wherever they
23
+ * appear, including split across reads, and holds a half-arrived sequence
24
+ * briefly so it cannot leak as `17;1R` digits either;
25
+ * - `TerminalInputPump` measures RTT by asking several times, discarding
26
+ * answers that cannot be a real round-trip, and reporting the middle one —
27
+ * an estimate of the link rather than of the current queue.
28
+ */
29
+ import { StringDecoder } from 'node:string_decoder';
30
+ /** True when this process is talking to a terminal through SSH. */
31
+ export function detectSshSession(env = process.env) {
32
+ return Boolean(env.SSH_CONNECTION || env.SSH_CLIENT || env.SSH_TTY);
33
+ }
34
+ /** Cursor position report: `CSI row ; col R` (`?` for DECXCPR). */
35
+ const CURSOR_REPLY = /\x1b\[\??\d+;\d+R/gu;
36
+ /** Longest run that can still grow into one: `\x1b[?12345;12345`. */
37
+ const CURSOR_PREFIX_MAX = 16;
38
+ /** A partial reply: `\x1b`, `\x1b[`, `\x1b[12;3`, but not `\x1b[1;2;3`. */
39
+ const CURSOR_PREFIX = /^\x1b(?:\[(?:\??(?:\d*(?:;\d*)?)?)?)?$/u;
40
+ /** What a probe writes to ask the terminal where its cursor is. */
41
+ export const CURSOR_POSITION_REQUEST = '\x1b[6n';
42
+ /**
43
+ * How long a half-arrived reply is held before it is handed over as typing.
44
+ * A real sequence arrives within one read or the next; anything slower is
45
+ * either a very unlucky split or the start of a user's own escape key.
46
+ */
47
+ export const INPUT_HOLD_MS = 30;
48
+ /** A single probe answer that misses this window counts as "no reply". */
49
+ export const RTT_SAMPLE_TIMEOUT_MS = 350;
50
+ /** Wider window for the rest of the measurement once one has been missed. */
51
+ export const RTT_SLOW_SAMPLE_TIMEOUT_MS = 800;
52
+ /** Answers to collect before one is reported. */
53
+ export const RTT_SAMPLE_COUNT = 3;
54
+ /** Two answers this close already describe the link; the third is not needed. */
55
+ export const RTT_AGREEMENT_MS = 6;
56
+ /** Rejected or lost answers do not consume the sampling budget. */
57
+ const RTT_EXTRA_ATTEMPTS = 3;
58
+ /** Wall-clock ceiling for one measurement, however chatty the terminal is. */
59
+ export const RTT_MEASURE_BUDGET_MS = 2_500;
60
+ /** Quiet time before re-asking when nothing was measured yet. */
61
+ const RTT_QUIET_MIN_MS = 150;
62
+ /** On top of the last good round-trip: how far behind it an answer can be. */
63
+ const RTT_QUIET_MARGIN_MS = 25;
64
+ /**
65
+ * An SSH answer that came back this much faster than the slowest sample cannot
66
+ * have made the round trip — it was already on the wire when we asked. Relative
67
+ * on purpose: `ssh localhost` honestly answers in about 2 ms.
68
+ */
69
+ export const RTT_OUTLIER_RATIO = 0.25;
70
+ /** Remove every complete cursor reply from `text`. */
71
+ export function stripCursorReplies(text) {
72
+ let replies = 0;
73
+ const cleaned = text.replace(CURSOR_REPLY, () => {
74
+ replies += 1;
75
+ return '';
76
+ });
77
+ return { text: cleaned, replies };
78
+ }
79
+ /** The trailing run of `text` that a reply could still grow out of. */
80
+ function cursorReplyTail(text) {
81
+ const start = text.lastIndexOf('\x1b');
82
+ if (start === -1)
83
+ return '';
84
+ const tail = text.slice(start);
85
+ if (tail.length > CURSOR_PREFIX_MAX || !CURSOR_PREFIX.test(tail))
86
+ return '';
87
+ return tail;
88
+ }
89
+ /**
90
+ * Drop cursor replies from a byte stream that is otherwise user input.
91
+ *
92
+ * Feed every read to `push()`; the bytes it returns are what the user actually
93
+ * typed. A read that ends in the middle of a possible reply is held back (see
94
+ * `flush()`) so `ESC [ 1` + `7;1R` cannot become visible digits either.
95
+ */
96
+ export class TerminalInputFilter {
97
+ held = '';
98
+ push(text) {
99
+ const { text: cleaned, replies } = stripCursorReplies(this.held + text);
100
+ this.held = '';
101
+ const tail = cursorReplyTail(cleaned);
102
+ if (tail === '')
103
+ return { forward: cleaned, replies };
104
+ this.held = tail;
105
+ return { forward: cleaned.slice(0, cleaned.length - tail.length), replies };
106
+ }
107
+ /** Release a held partial (its window passed, so it was not a reply). */
108
+ flush() {
109
+ const held = this.held;
110
+ this.held = '';
111
+ return held;
112
+ }
113
+ /** Forget a held partial — used when the caller knows it must be stale. */
114
+ reset() {
115
+ this.held = '';
116
+ }
117
+ get pending() {
118
+ return this.held !== '';
119
+ }
120
+ }
121
+ /**
122
+ * The filter with the hold timer attached, for a caller that turns bytes into
123
+ * keystrokes (the TUI and the session picker) instead of forwarding them.
124
+ */
125
+ export class TerminalInputGuard {
126
+ emit;
127
+ holdMs;
128
+ filter = new TerminalInputFilter();
129
+ timer;
130
+ constructor(emit, holdMs = INPUT_HOLD_MS) {
131
+ this.emit = emit;
132
+ this.holdMs = holdMs;
133
+ }
134
+ /** Feed one decoded read; anything that is not a reply reaches `emit`. */
135
+ push(text) {
136
+ const { forward } = this.filter.push(text);
137
+ if (this.filter.pending) {
138
+ if (this.timer !== undefined)
139
+ clearTimeout(this.timer);
140
+ this.timer = setTimeout(() => {
141
+ this.timer = undefined;
142
+ this.release();
143
+ }, this.holdMs);
144
+ this.timer.unref?.();
145
+ }
146
+ if (forward !== '')
147
+ this.emit(forward);
148
+ }
149
+ /** Hand a half-arrived sequence over (its window passed; it is typing). */
150
+ release() {
151
+ if (this.timer !== undefined) {
152
+ clearTimeout(this.timer);
153
+ this.timer = undefined;
154
+ }
155
+ const held = this.filter.flush();
156
+ if (held !== '')
157
+ this.emit(held);
158
+ }
159
+ /** Drop the timer and any held bytes (display detached, picker settled). */
160
+ stop() {
161
+ if (this.timer !== undefined) {
162
+ clearTimeout(this.timer);
163
+ this.timer = undefined;
164
+ }
165
+ this.filter.reset();
166
+ }
167
+ }
168
+ /**
169
+ * stdin → replies (for the probe) + real input (for the caller).
170
+ *
171
+ * Long-lived on purpose: the relay keeps it running for the whole attachment,
172
+ * so a reply that arrives seconds late is dropped instead of reaching the Host.
173
+ */
174
+ export class TerminalInputPump {
175
+ options;
176
+ filter = new TerminalInputFilter();
177
+ decoder = new StringDecoder('utf8');
178
+ waiters = [];
179
+ /** When the last answer (accepted or not) arrived; drives the quiet wait. */
180
+ lastAnswerAt = 0;
181
+ /** When the last request went out; an answer may follow it for a window. */
182
+ lastRequestAt = 0;
183
+ /** Current answer window; widened once when the first one is missed. */
184
+ windowMs = RTT_SAMPLE_TIMEOUT_MS;
185
+ /** Answers seen, used to tell "slow terminal" from "terminal never answers". */
186
+ answersSeen = 0;
187
+ /** Slowest sample so far; the quiet wait has to clear the worst of them. */
188
+ slowestSampleMs;
189
+ holdTimer;
190
+ listening = false;
191
+ ssh;
192
+ constructor(options) {
193
+ this.options = options;
194
+ this.ssh = options.ssh ?? detectSshSession();
195
+ }
196
+ start() {
197
+ if (this.listening)
198
+ return;
199
+ this.listening = true;
200
+ this.options.stdin.on('data', this.onData);
201
+ }
202
+ stop() {
203
+ const wasListening = this.listening;
204
+ this.listening = false;
205
+ if (wasListening)
206
+ this.options.stdin.removeListener('data', this.onData);
207
+ if (this.holdTimer !== undefined) {
208
+ clearTimeout(this.holdTimer);
209
+ this.holdTimer = undefined;
210
+ }
211
+ for (const waiter of this.waiters.splice(0)) {
212
+ clearTimeout(waiter.timer);
213
+ waiter.settle(undefined);
214
+ }
215
+ const held = this.filter.flush();
216
+ if (held !== '')
217
+ this.options.onInput(held);
218
+ const tail = this.decoder.end();
219
+ if (tail !== '')
220
+ this.options.onInput(tail);
221
+ }
222
+ /**
223
+ * Ask the terminal for its cursor a few times and report the round-trip that
224
+ * best describes the link. `undefined` means the terminal never answered in
225
+ * time (a dumb pipe), and the caller must not treat that as "0 ms".
226
+ */
227
+ async measure() {
228
+ const timeoutMs = this.options.sampleTimeoutMs ?? RTT_SAMPLE_TIMEOUT_MS;
229
+ this.windowMs = timeoutMs;
230
+ const wanted = Math.max(1, this.options.samples ?? RTT_SAMPLE_COUNT);
231
+ const samples = [];
232
+ const note = this.options.debug;
233
+ let misses = 0;
234
+ let attempts = 0;
235
+ // A rejected or lost answer must not eat the budget: on a reconnect the
236
+ // terminal can still be finishing a dead launcher's probe.
237
+ const maxAttempts = wanted + RTT_EXTRA_ATTEMPTS;
238
+ const budgetMs = this.options.budgetMs ?? RTT_MEASURE_BUDGET_MS;
239
+ const startedAt = Date.now();
240
+ const answersAtStart = this.answersSeen;
241
+ this.lastAnswerAt = startedAt;
242
+ while (samples.length < wanted && attempts < maxAttempts
243
+ && Date.now() - startedAt < budgetMs) {
244
+ attempts += 1;
245
+ // Never ask while an earlier request may still be in flight: its answer
246
+ // would be read as this request's, and because it left earlier it is
247
+ // *faster* — the "2 ms on a 50 ms link" reading. Wait for the whole
248
+ // answer window to go by before asking again.
249
+ if (attempts > 1)
250
+ await this.quiet(startedAt + budgetMs);
251
+ this.drain();
252
+ const rtt = await this.ask(this.windowMs);
253
+ if (rtt === undefined) {
254
+ misses += 1;
255
+ note?.(`rtt probe ${attempts}: no answer`);
256
+ // A miss may just mean the link is slower than the first window, so
257
+ // widen it — but only for a terminal that has answered at all: a dumb
258
+ // pipe must not cost the widened window twice.
259
+ if (this.answersSeen > answersAtStart) {
260
+ this.windowMs = Math.min(RTT_SLOW_SAMPLE_TIMEOUT_MS, Math.max(this.windowMs, timeoutMs * 3));
261
+ }
262
+ // Two silent windows in a row and nothing collected: this terminal
263
+ // does not answer DSR at all, and a third only delays the attach.
264
+ if (misses >= 2 && samples.length === 0)
265
+ break;
266
+ continue;
267
+ }
268
+ samples.push(rtt);
269
+ note?.(`rtt probe ${attempts}: ${rtt}ms`);
270
+ if (samples.length >= 2
271
+ && Math.max(...samples) - Math.min(...samples) <= RTT_AGREEMENT_MS)
272
+ break;
273
+ }
274
+ // Whatever else was queued belongs to a request we have already given up
275
+ // on; it must not reach the Host, and it must not extend this measurement.
276
+ this.drain();
277
+ const kept = this.dropFastOutliers(samples);
278
+ // Median of three, not the minimum: one answer that was already in flight
279
+ // when we asked is *fast*, and taking the smallest sample let it decide the
280
+ // footer's chip. Two samples only get here when they already agree (the
281
+ // early stop above), and the larger one is the conservative pick.
282
+ const measured = kept.length === 0
283
+ ? undefined
284
+ : kept.length >= 3
285
+ ? [...kept].sort((a, b) => a - b)[Math.floor(kept.length / 2)]
286
+ : Math.max(...kept);
287
+ note?.(measured === undefined
288
+ ? 'rtt probe: unknown'
289
+ : `rtt probe: ${measured}ms (of ${samples.map(value => `${value}ms`).join(', ')})`);
290
+ return measured;
291
+ }
292
+ /**
293
+ * Drop an answer that came back far too fast to have made the round trip —
294
+ * an answer to somebody else's request, still on the wire when we asked.
295
+ * Relative, not absolute (`ssh localhost` honestly answers in 2 ms), and
296
+ * measured against the *median*: comparing with the slowest sample would
297
+ * throw away three good answers because one request sat behind a repaint.
298
+ */
299
+ dropFastOutliers(samples) {
300
+ if (!this.ssh || samples.length < 2)
301
+ return samples;
302
+ const sorted = [...samples].sort((a, b) => a - b);
303
+ const middle = Math.floor(sorted.length / 2);
304
+ const median = sorted.length % 2 === 1
305
+ ? (sorted[middle] ?? 0)
306
+ : ((sorted[middle - 1] ?? 0) + (sorted[middle] ?? 0)) / 2;
307
+ return samples.filter(sample => sample >= median * RTT_OUTLIER_RATIO);
308
+ }
309
+ /**
310
+ * How long the line must be quiet before the next request may go out.
311
+ *
312
+ * The only safe answer is the full sample window: a request we sent can be
313
+ * answered at any point inside it, so anything shorter can attribute that
314
+ * answer to the request that follows. Deriving it from the samples instead
315
+ * looks cheaper and is exactly what goes wrong — a leftover answer reports
316
+ * 1 ms, the window shrinks to the minimum, and the honest answer to the
317
+ * abandoned request lands in the *next* window (250 ms link reported as 1 ms
318
+ * and 0 ms, two "agreeing" samples, early stop, chip frozen on a wrong value).
319
+ */
320
+ quietMs() {
321
+ if (this.slowestSampleMs === undefined)
322
+ return Math.max(RTT_QUIET_MIN_MS, this.windowMs);
323
+ return Math.max(RTT_QUIET_MIN_MS, this.windowMs, this.slowestSampleMs + RTT_QUIET_MARGIN_MS);
324
+ }
325
+ /**
326
+ * Wait until the line has been quiet for a full window, measured from the
327
+ * later of the last answer and the last request. An answer to a request we
328
+ * already gave up on lands in here and is thrown away, so it cannot be
329
+ * attributed to the request that follows it.
330
+ */
331
+ async quiet(deadline) {
332
+ const quietMs = this.quietMs();
333
+ for (;;) {
334
+ const last = Math.max(this.lastAnswerAt, this.lastRequestAt);
335
+ const idle = Date.now() - last;
336
+ if (idle >= quietMs)
337
+ return;
338
+ if (Date.now() >= deadline)
339
+ return;
340
+ await new Promise(resolve => setTimeout(resolve, Math.min(20, quietMs - idle)));
341
+ }
342
+ }
343
+ /**
344
+ * Consume what the kernel already holds, so an answer that was on its way
345
+ * before this request cannot be read as its answer.
346
+ *
347
+ * `read()` emits `data` for the chunk it returns whenever a listener is
348
+ * attached, and the listener path would then deliver the same bytes twice
349
+ * (a typed `hi` arrived at the Host as `hihi`). Detach for the duration of
350
+ * the loop: it is synchronous, so nothing can be lost in between.
351
+ */
352
+ drain() {
353
+ const read = this.options.stdin.read;
354
+ const listening = this.listening;
355
+ if (listening && typeof read === 'function')
356
+ this.options.stdin.removeListener('data', this.onData);
357
+ try {
358
+ if (typeof read === 'function') {
359
+ for (;;) {
360
+ let chunk;
361
+ try {
362
+ chunk = read.call(this.options.stdin);
363
+ }
364
+ catch {
365
+ break;
366
+ }
367
+ if (chunk === null || chunk === undefined)
368
+ break;
369
+ if (chunk.length === 0)
370
+ break;
371
+ this.feed(chunk);
372
+ }
373
+ }
374
+ }
375
+ finally {
376
+ if (listening)
377
+ this.options.stdin.on('data', this.onData);
378
+ }
379
+ if (this.holdTimer !== undefined) {
380
+ clearTimeout(this.holdTimer);
381
+ this.holdTimer = undefined;
382
+ }
383
+ // A half-arrived sequence sitting here now predates the request we are
384
+ // about to send, so it cannot be its answer.
385
+ this.filter.reset();
386
+ }
387
+ ask(timeoutMs) {
388
+ return new Promise(resolve => {
389
+ let settled = false;
390
+ const settle = (value) => {
391
+ if (settled)
392
+ return;
393
+ settled = true;
394
+ resolve(value);
395
+ };
396
+ const waiter = {
397
+ started: Date.now(),
398
+ settle,
399
+ timer: setTimeout(() => {
400
+ const index = this.waiters.indexOf(waiter);
401
+ if (index !== -1)
402
+ this.waiters.splice(index, 1);
403
+ settle(undefined);
404
+ }, timeoutMs),
405
+ };
406
+ waiter.timer.unref?.();
407
+ this.waiters.push(waiter);
408
+ this.lastRequestAt = Date.now();
409
+ try {
410
+ this.options.stdout.write(CURSOR_POSITION_REQUEST);
411
+ }
412
+ catch {
413
+ const index = this.waiters.indexOf(waiter);
414
+ if (index !== -1)
415
+ this.waiters.splice(index, 1);
416
+ clearTimeout(waiter.timer);
417
+ settle(undefined);
418
+ }
419
+ });
420
+ }
421
+ onData = (chunk) => {
422
+ this.feed(chunk);
423
+ };
424
+ feed(chunk) {
425
+ const text = typeof chunk === 'string' ? chunk : this.decoder.write(chunk);
426
+ if (text === '')
427
+ return;
428
+ const { forward, replies } = this.filter.push(text);
429
+ for (let index = 0; index < replies; index += 1)
430
+ this.answer();
431
+ if (forward !== '')
432
+ this.options.onInput(forward);
433
+ this.scheduleHold();
434
+ }
435
+ /**
436
+ * One reply: hand it to the oldest outstanding request. An answer that
437
+ * belongs to a request we already gave up on is simply dropped here — and
438
+ * its arrival time still restarts the quiet window, which is what keeps it
439
+ * from being attributed to the next request.
440
+ */
441
+ answer() {
442
+ this.lastAnswerAt = Date.now();
443
+ this.answersSeen += 1;
444
+ const waiter = this.waiters.shift();
445
+ if (waiter === undefined)
446
+ return;
447
+ clearTimeout(waiter.timer);
448
+ const elapsed = Math.max(0, Date.now() - waiter.started);
449
+ if (this.slowestSampleMs === undefined || elapsed > this.slowestSampleMs) {
450
+ this.slowestSampleMs = elapsed;
451
+ }
452
+ waiter.settle(elapsed);
453
+ }
454
+ scheduleHold() {
455
+ if (this.holdTimer !== undefined) {
456
+ clearTimeout(this.holdTimer);
457
+ this.holdTimer = undefined;
458
+ }
459
+ if (!this.filter.pending)
460
+ return;
461
+ this.holdTimer = setTimeout(() => {
462
+ this.holdTimer = undefined;
463
+ const held = this.filter.flush();
464
+ if (held !== '')
465
+ this.options.onInput(held);
466
+ }, this.options.holdMs ?? INPUT_HOLD_MS);
467
+ this.holdTimer.unref?.();
468
+ }
469
+ }
470
+ //# sourceMappingURL=terminal-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-input.js","sourceRoot":"","sources":["../src/terminal-input.ts"],"names":[],"mappings":"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"}