dsh-ssh-tui 0.8.0 → 0.8.2-rc.1
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 +150 -0
- package/README.en.md +74 -8
- package/README.md +451 -577
- package/docs/display-mode.md +122 -0
- package/docs/release-notes-0.7.4.md +91 -0
- package/docs/release-notes-0.8.0.md +56 -0
- package/docs/release-notes-0.8.1.md +79 -0
- package/docs/release-notes-0.8.2-rc.1.md +159 -0
- package/docs/remote-ops.md +51 -0
- package/docs/terminals.md +53 -0
- package/docs/windows.md +13 -0
- package/lib/approval-state.js +148 -0
- package/lib/approval-state.js.map +1 -0
- package/lib/attach.js +4 -4
- package/lib/attach.js.map +1 -1
- package/lib/auth-failure.js +74 -0
- package/lib/auth-failure.js.map +1 -1
- package/lib/color-depth.js +26 -0
- package/lib/color-depth.js.map +1 -1
- package/lib/commands.js +2 -0
- package/lib/commands.js.map +1 -1
- package/lib/copy-text.js +30 -8
- package/lib/copy-text.js.map +1 -1
- package/lib/dialogs.js +124 -0
- package/lib/dialogs.js.map +1 -1
- package/lib/display-mode.js +147 -0
- package/lib/display-mode.js.map +1 -0
- package/lib/display-sock.js +490 -35
- package/lib/display-sock.js.map +1 -1
- package/lib/footer-accents.js +28 -0
- package/lib/footer-accents.js.map +1 -0
- package/lib/footer-budget.js +328 -0
- package/lib/footer-budget.js.map +1 -0
- package/lib/footer-format.js +433 -0
- package/lib/footer-format.js.map +1 -0
- package/lib/footer-layout.js +407 -0
- package/lib/footer-layout.js.map +1 -0
- package/lib/footer-meters.js +185 -0
- package/lib/footer-meters.js.map +1 -0
- package/lib/footer.js +19 -561
- package/lib/footer.js.map +1 -1
- package/lib/glyph-measure.js +92 -0
- package/lib/glyph-measure.js.map +1 -0
- package/lib/i18n/en.js +83 -7
- package/lib/i18n/en.js.map +1 -1
- package/lib/i18n/zh.js +85 -7
- package/lib/i18n/zh.js.map +1 -1
- package/lib/index.js +73 -5
- package/lib/index.js.map +1 -1
- package/lib/paint.js +75 -17
- package/lib/paint.js.map +1 -1
- package/lib/picker.js +14 -13
- package/lib/picker.js.map +1 -1
- package/lib/plan-projection.js +291 -0
- package/lib/plan-projection.js.map +1 -0
- package/lib/plan.js +61 -11
- package/lib/plan.js.map +1 -1
- package/lib/platform.js +96 -0
- package/lib/platform.js.map +1 -1
- package/lib/question-state.js +83 -0
- package/lib/question-state.js.map +1 -0
- package/lib/representation.js +283 -0
- package/lib/representation.js.map +1 -0
- package/lib/screen.js +105 -0
- package/lib/screen.js.map +1 -0
- package/lib/selection.js +5 -3
- package/lib/selection.js.map +1 -1
- package/lib/session-blank.js +81 -0
- package/lib/session-blank.js.map +1 -0
- package/lib/session-list.js +102 -81
- package/lib/session-list.js.map +1 -1
- package/lib/startup.js +56 -0
- package/lib/startup.js.map +1 -1
- package/lib/stats.js +101 -3
- package/lib/stats.js.map +1 -1
- package/lib/subagent-model.js +8 -7
- package/lib/subagent-model.js.map +1 -1
- package/lib/term-text.js +436 -69
- package/lib/term-text.js.map +1 -1
- package/lib/terminal-input.js +132 -10
- package/lib/terminal-input.js.map +1 -1
- package/lib/theme.js +335 -0
- package/lib/theme.js.map +1 -0
- package/lib/throughput.js +305 -0
- package/lib/throughput.js.map +1 -0
- package/lib/tool-present.js +67 -15
- package/lib/tool-present.js.map +1 -1
- package/lib/tui.js +4186 -1133
- package/lib/tui.js.map +1 -1
- package/lib/types/approval-state.d.ts +75 -0
- package/lib/types/attach.d.ts +6 -2
- package/lib/types/auth-failure.d.ts +55 -0
- package/lib/types/color-depth.d.ts +21 -0
- package/lib/types/commands.d.ts +6 -0
- package/lib/types/copy-text.d.ts +18 -1
- package/lib/types/dialogs.d.ts +147 -1
- package/lib/types/display-mode.d.ts +99 -0
- package/lib/types/display-sock.d.ts +90 -0
- package/lib/types/footer-accents.d.ts +22 -0
- package/lib/types/footer-budget.d.ts +204 -0
- package/lib/types/footer-format.d.ts +221 -0
- package/lib/types/footer-layout.d.ts +292 -0
- package/lib/types/footer-meters.d.ts +151 -0
- package/lib/types/footer.d.ts +19 -269
- package/lib/types/glyph-measure.d.ts +41 -0
- package/lib/types/index.d.ts +13 -0
- package/lib/types/paint.d.ts +48 -0
- package/lib/types/plan-projection.d.ts +162 -0
- package/lib/types/plan.d.ts +18 -2
- package/lib/types/platform.d.ts +83 -0
- package/lib/types/question-state.d.ts +96 -0
- package/lib/types/representation.d.ts +498 -0
- package/lib/types/screen.d.ts +126 -0
- package/lib/types/session-blank.d.ts +51 -0
- package/lib/types/session-list.d.ts +34 -0
- package/lib/types/startup.d.ts +30 -0
- package/lib/types/stats.d.ts +64 -1
- package/lib/types/subagent-model.d.ts +7 -6
- package/lib/types/term-text.d.ts +100 -24
- package/lib/types/terminal-input.d.ts +37 -0
- package/lib/types/theme.d.ts +109 -0
- package/lib/types/throughput.d.ts +163 -0
- package/lib/types/tool-present.d.ts +43 -2
- package/lib/types/transcript-types.d.ts +63 -2
- package/lib/types/tui.d.ts +960 -12
- package/package.json +73 -67
package/lib/dialogs.js
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
/** Whether this is a dialog the live path can own (see {@link SurfaceDialog}). */
|
|
2
|
+
export function isSurfaceDialog(dialog) {
|
|
3
|
+
return dialog.kind === 'confirm' || dialog.kind === 'questions';
|
|
4
|
+
}
|
|
5
|
+
/** The roles as values, so no call site invents its own object. */
|
|
6
|
+
export const PICKER_ROLE = { kind: 'picker' };
|
|
7
|
+
export function interactionRole(ask) {
|
|
8
|
+
return { kind: 'interaction', ask };
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Whether a role means the task is stopped waiting for the human.
|
|
12
|
+
*
|
|
13
|
+
* A local `confirm` (deleting a preset, repairing the profile) owns the keyboard
|
|
14
|
+
* too, but the agent is not waiting on it — reporting it as a wait is the same
|
|
15
|
+
* class of mistake as reporting a picker as one.
|
|
16
|
+
*/
|
|
17
|
+
export function stallsTask(role) {
|
|
18
|
+
return role?.kind === 'interaction' && role.ask !== 'confirm';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Which surface gets the keyboard first when more than one is waiting (B1.2).
|
|
22
|
+
*
|
|
23
|
+
* Only one transient surface is ever drawn, so this is not a z-order: it decides
|
|
24
|
+
* who is *next in line*. A task interaction outranks a picker (someone is blocked on
|
|
25
|
+
* it, and the agent cannot proceed), and a picker outranks whatever the reader was
|
|
26
|
+
* about to type. Equal ranks keep their arrival order, so a queue of two pickers
|
|
27
|
+
* still behaves exactly as it did before.
|
|
28
|
+
*
|
|
29
|
+
* A Screen is not in this ordering at all: it is not a surface (B2.6 §1).
|
|
30
|
+
*/
|
|
31
|
+
export function surfacePriority(role) {
|
|
32
|
+
return role.kind === 'interaction' ? 1 : 0;
|
|
33
|
+
}
|
|
1
34
|
/** Digits then letters: the hotkeys painted next to question options. */
|
|
2
35
|
export const QUESTION_OPTION_KEYS = '123456789abcdefghijklmnopqrstuvwxyz';
|
|
3
36
|
/** Options a dialog can answer with; only a question list has any. */
|
|
@@ -90,12 +123,55 @@ export function moveQuestionCursor(dialog, delta) {
|
|
|
90
123
|
? (delta >= 0 ? visible[0] : visible[visible.length - 1])
|
|
91
124
|
: visible[Math.max(0, Math.min(visible.length - 1, at + delta))];
|
|
92
125
|
dialog.cursor = next ?? dialog.cursor;
|
|
126
|
+
dialog.onCursor?.(dialog.cursor);
|
|
93
127
|
if (dialog.question.multiSelect !== true) {
|
|
94
128
|
dialog.selected.clear();
|
|
95
129
|
dialog.selected.add(dialog.cursor);
|
|
96
130
|
}
|
|
97
131
|
return true;
|
|
98
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Which options a fresh question dialog starts with.
|
|
135
|
+
*
|
|
136
|
+
* The rule that caused a real mis-answer: a **multi-select** list used to inherit
|
|
137
|
+
* the single-select default of "the first option is already chosen", so a reader
|
|
138
|
+
* who moved the highlight to the row they wanted and pressed Enter answered with
|
|
139
|
+
* the first row instead — the `●` never left it. A multi-select starts empty
|
|
140
|
+
* unless the caller asks for a specific preselection; `questionSubmit` then falls
|
|
141
|
+
* back to the highlighted row, which is what pressing Enter means.
|
|
142
|
+
* @param question - the question being asked.
|
|
143
|
+
* @param preselected - an index the caller wants chosen up front, if any.
|
|
144
|
+
* @returns the indexes to select initially.
|
|
145
|
+
*/
|
|
146
|
+
export function initialQuestionSelection(question, preselected) {
|
|
147
|
+
const count = question.options?.length ?? 0;
|
|
148
|
+
if (count === 0)
|
|
149
|
+
return [];
|
|
150
|
+
const wanted = preselected !== undefined && preselected >= 0 && preselected < count ? preselected : undefined;
|
|
151
|
+
if (question.multiSelect === true)
|
|
152
|
+
return wanted === undefined ? [] : [wanted];
|
|
153
|
+
return [wanted ?? 0];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The circle drawn beside one option.
|
|
157
|
+
*
|
|
158
|
+
* `●` marks **what Enter will submit**, which is why it sits on the highlighted
|
|
159
|
+
* row while nothing is ticked — the mark follows the cursor, so what the reader
|
|
160
|
+
* sees is what the answer will be. A ticked row in a multi-select list carries
|
|
161
|
+
* `✓` instead: several rows can be chosen at once, and the circle cannot be in
|
|
162
|
+
* two places without lying about one of them.
|
|
163
|
+
* @param dialog - the open question dialog.
|
|
164
|
+
* @param index - the option index being drawn.
|
|
165
|
+
* @returns the marker for that row.
|
|
166
|
+
*/
|
|
167
|
+
export function questionOptionMarker(dialog, index) {
|
|
168
|
+
const toggled = dialog.selected.has(index);
|
|
169
|
+
if (dialog.question.multiSelect !== true)
|
|
170
|
+
return index === dialog.cursor ? '●' : '○';
|
|
171
|
+
if (toggled)
|
|
172
|
+
return '✓';
|
|
173
|
+
return index === dialog.cursor && dialog.selected.size === 0 ? '●' : '○';
|
|
174
|
+
}
|
|
99
175
|
/** Select option `index`: toggles in a multi-select list, replaces otherwise. */
|
|
100
176
|
export function selectQuestionOption(dialog, index) {
|
|
101
177
|
dialog.cursor = index;
|
|
@@ -158,4 +234,52 @@ export function confirmAnswer(text) {
|
|
|
158
234
|
export function inspectClosesOn(text) {
|
|
159
235
|
return text === '\x1b' || text === '\x03' || text === 'q' || text === 'Q' || text === '\r' || text === '\n';
|
|
160
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* Fit an interaction's rendered lines into the rows the frame can give it.
|
|
239
|
+
*
|
|
240
|
+
* The interaction layer is composed *over* the transcript (see `paintFrame`), and
|
|
241
|
+
* the space above the composer is whatever the terminal has left after the footer,
|
|
242
|
+
* the composer and the header. On a short terminal that can be fewer rows than a
|
|
243
|
+
* question list needs — and clipping the *bottom* would hide the options and the
|
|
244
|
+
* key hint, which is exactly the part that has to stay reachable. So the window
|
|
245
|
+
* keeps the focused row visible and marks what it dropped.
|
|
246
|
+
*
|
|
247
|
+
* @param lines - the interaction as its renderer drew it, top to bottom.
|
|
248
|
+
* @param cap - how many rows the frame has for it.
|
|
249
|
+
* @param focusLine - index of the row that must stay visible (the highlighted
|
|
250
|
+
* option, or the prompt when there is no list).
|
|
251
|
+
* @returns the rows to place, top to bottom, at most `cap` of them.
|
|
252
|
+
*/
|
|
253
|
+
export function windowInteractionLines(lines, cap, focusLine) {
|
|
254
|
+
if (cap <= 0)
|
|
255
|
+
return { lines: [], hiddenAbove: lines.length, hiddenBelow: 0 };
|
|
256
|
+
if (lines.length <= cap)
|
|
257
|
+
return { lines: [...lines], hiddenAbove: 0, hiddenBelow: 0 };
|
|
258
|
+
// One row is spent on the "there is more" marker, so the reader can tell a
|
|
259
|
+
// clipped list from a short one.
|
|
260
|
+
const room = Math.max(1, cap - 1);
|
|
261
|
+
// The last line is the key hint: it is what says how to answer, so it is kept
|
|
262
|
+
// even when the window has to drop the middle of the interaction. Only when
|
|
263
|
+
// doing so would leave no room for the focused row does it go.
|
|
264
|
+
const tail = lines[lines.length - 1];
|
|
265
|
+
const keepTail = lines.length > 1 && room >= 3 && (focusLine ?? 0) < lines.length - 1;
|
|
266
|
+
const body = keepTail ? lines.slice(0, -1) : lines;
|
|
267
|
+
const rows = keepTail ? room - 1 : room;
|
|
268
|
+
const focus = Math.max(0, Math.min(body.length - 1, focusLine ?? body.length - 1));
|
|
269
|
+
let start = Math.max(0, Math.min(body.length - rows, focus - Math.floor(rows / 2)));
|
|
270
|
+
// The focus must be inside the window whatever the centring worked out to.
|
|
271
|
+
if (focus < start)
|
|
272
|
+
start = focus;
|
|
273
|
+
if (focus >= start + rows)
|
|
274
|
+
start = focus - rows + 1;
|
|
275
|
+
start = Math.max(0, Math.min(start, body.length - rows));
|
|
276
|
+
const kept = body.slice(start, start + rows);
|
|
277
|
+
const hiddenAbove = start;
|
|
278
|
+
const hiddenBelow = body.length - start - rows;
|
|
279
|
+
return {
|
|
280
|
+
lines: [`… ${hiddenAbove + hiddenBelow}`, ...kept, ...(keepTail ? [tail] : [])],
|
|
281
|
+
hiddenAbove,
|
|
282
|
+
hiddenBelow,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
161
285
|
//# sourceMappingURL=dialogs.js.map
|
package/lib/dialogs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialogs.js","sourceRoot":"","sources":["../src/dialogs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dialogs.js","sourceRoot":"","sources":["../src/dialogs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the TUI's bytes go when the parent is not a terminal.
|
|
3
|
+
*
|
|
4
|
+
* The plugin paints through a display relay, and a relay normally *is* a
|
|
5
|
+
* terminal: it writes ANSI to stdout, listens for `resize`, and puts stdin in raw
|
|
6
|
+
* mode. A GUI, a browser terminal or a test harness has none of those, but it can
|
|
7
|
+
* provide the same three things over pipes — bytes in, bytes out, and a size it
|
|
8
|
+
* reports as a protocol frame. This module is the switch that says "the parent is
|
|
9
|
+
* such a relay, do not require a TTY".
|
|
10
|
+
*
|
|
11
|
+
* Two entries, one mechanism and one sugar (as chosen when the mode was
|
|
12
|
+
* designed):
|
|
13
|
+
*
|
|
14
|
+
* - `DSH_TUI_DISPLAY=stdio` in the environment — the mechanism. Setting it *is*
|
|
15
|
+
* the parent's statement that it is a relay, so it is also what the no-TTY
|
|
16
|
+
* guard consults.
|
|
17
|
+
* - `--display stdio` on the command line — the sugar, declared in the profile's
|
|
18
|
+
* own grammar so it shows up in `--help` and a typo is an error rather than a
|
|
19
|
+
* silently inert plugin.
|
|
20
|
+
*
|
|
21
|
+
* @module dsh-ssh-tui/display-mode
|
|
22
|
+
*/
|
|
23
|
+
/** The environment variable that selects the display mode. */
|
|
24
|
+
export const DISPLAY_MODE_ENV = 'DSH_TUI_DISPLAY';
|
|
25
|
+
/**
|
|
26
|
+
* Parse one mode word.
|
|
27
|
+
* @param value - a value from the environment or a flag.
|
|
28
|
+
* @returns the mode, or undefined for anything else (the caller reports it).
|
|
29
|
+
*/
|
|
30
|
+
export function parseDisplayMode(value) {
|
|
31
|
+
const raw = String(value ?? '').trim().toLowerCase();
|
|
32
|
+
return raw === 'stdio' || raw === 'tty' ? raw : undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The `--display <mode>` value in an argument vector.
|
|
36
|
+
*
|
|
37
|
+
* Accepts both spellings a person may type (`--display stdio`,
|
|
38
|
+
* `--display=stdio`) and only ever reads the pair it owns — everything else is
|
|
39
|
+
* left where it is, because the same vector is parsed by the profile's own
|
|
40
|
+
* grammar and by the host.
|
|
41
|
+
* @param argv - an argument vector (defaults to this process's).
|
|
42
|
+
* @returns the value found, if any.
|
|
43
|
+
*/
|
|
44
|
+
export function displayModeFromArgv(argv = process.argv) {
|
|
45
|
+
for (let at = 0; at < argv.length; at += 1) {
|
|
46
|
+
const arg = argv[at] ?? '';
|
|
47
|
+
if (arg.startsWith('--display='))
|
|
48
|
+
return arg.slice('--display='.length);
|
|
49
|
+
if (arg === '--display') {
|
|
50
|
+
const next = argv[at + 1];
|
|
51
|
+
// A missing value is not silently "the default": leave it to the grammar,
|
|
52
|
+
// which turns it into a usage error.
|
|
53
|
+
return next === undefined || next.startsWith('-') ? '' : next;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the mode request from the environment and the command line.
|
|
60
|
+
*
|
|
61
|
+
* The environment wins when both are present: it is the mechanism, and a parent
|
|
62
|
+
* that sets it is describing the channel it is about to speak on, whereas a flag
|
|
63
|
+
* is a convenience the reader may have left in a wrapper script.
|
|
64
|
+
* @param env - the environment to read.
|
|
65
|
+
* @param argv - the argument vector to read.
|
|
66
|
+
* @returns the requested mode, plus the offending value when one was useless.
|
|
67
|
+
*/
|
|
68
|
+
export function requestedDisplayMode(env = process.env, argv = process.argv) {
|
|
69
|
+
const fromEnv = env[DISPLAY_MODE_ENV];
|
|
70
|
+
if (fromEnv !== undefined && String(fromEnv).trim() !== '') {
|
|
71
|
+
const mode = parseDisplayMode(fromEnv);
|
|
72
|
+
return mode === undefined ? { invalid: String(fromEnv).trim() } : { mode };
|
|
73
|
+
}
|
|
74
|
+
const fromArgv = displayModeFromArgv(argv);
|
|
75
|
+
if (fromArgv === undefined || fromArgv === '')
|
|
76
|
+
return {};
|
|
77
|
+
const mode = parseDisplayMode(fromArgv);
|
|
78
|
+
return mode === undefined ? { invalid: fromArgv } : { mode };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A window-size report: `CSI 8 ; rows ; cols t`.
|
|
82
|
+
*
|
|
83
|
+
* This is the sequence a terminal sends when it is asked for its size, and it is
|
|
84
|
+
* also how a pipe parent says "the panel is now this big". A pipe has no
|
|
85
|
+
* `resize` event and no SIGWINCH, so without this the embedder's only way to
|
|
86
|
+
* resize the TUI would be to restart it.
|
|
87
|
+
*/
|
|
88
|
+
export const WINDOW_SIZE_REPORT = /\u001b\[8;(\d+);(\d+)t/gu;
|
|
89
|
+
/** Longest run that can still grow into a window-size report. */
|
|
90
|
+
const PARTIAL_REPORT_MAX = 16;
|
|
91
|
+
/** `ESC`, `ESC [`, `ESC [ 8`, `ESC [ 8 ; 24`, … — but not a finished report. */
|
|
92
|
+
const PARTIAL_REPORT = /^\u001b(?:\[(?:8(?:;(?:\d*(?:;\d*)?)?)?)?)?$/u;
|
|
93
|
+
/**
|
|
94
|
+
* Split a parent's input into keystrokes and size reports.
|
|
95
|
+
*
|
|
96
|
+
* A report can arrive split across two reads (`ESC [ 8 ; 2` then `4 ; 80 t`),
|
|
97
|
+
* and forwarding half of it as typing would send escape bytes to the model's
|
|
98
|
+
* prompt. The tail is held until the next read, exactly like the cursor-reply
|
|
99
|
+
* filter holds a half-arrived reply — with the same deadline that filter gets:
|
|
100
|
+
* a lone `ESC` matches the prefix, and the byte after it may never come, so a
|
|
101
|
+
* caller that forwards typing **must** release a {@link pending} run when its
|
|
102
|
+
* window passes (`flush()`). Waiting for the next read instead swallows the
|
|
103
|
+
* user's Escape key, and delivers it glued to whatever key follows as an Alt
|
|
104
|
+
* chord. `TerminalInputGuard` is the same filter with that timer attached.
|
|
105
|
+
* @returns a filter for one input stream.
|
|
106
|
+
*/
|
|
107
|
+
export function createParentResizeFilter() {
|
|
108
|
+
let held = '';
|
|
109
|
+
return {
|
|
110
|
+
push(text) {
|
|
111
|
+
const sizes = [];
|
|
112
|
+
const combined = held + text;
|
|
113
|
+
held = '';
|
|
114
|
+
let forward = '';
|
|
115
|
+
let cursor = 0;
|
|
116
|
+
for (const match of combined.matchAll(WINDOW_SIZE_REPORT)) {
|
|
117
|
+
const at = match.index ?? 0;
|
|
118
|
+
forward += combined.slice(cursor, at);
|
|
119
|
+
cursor = at + match[0].length;
|
|
120
|
+
// `CSI 8 ; rows ; cols t`: rows is the first number, columns the second.
|
|
121
|
+
const rows = Number(match[1]);
|
|
122
|
+
const columns = Number(match[2]);
|
|
123
|
+
// A zero dimension is a malformed report, not a request to hide the TUI.
|
|
124
|
+
if (rows > 0 && columns > 0)
|
|
125
|
+
sizes.push({ columns, rows });
|
|
126
|
+
}
|
|
127
|
+
const rest = combined.slice(cursor);
|
|
128
|
+
// Only the run from the last ESC can still grow into a report; everything
|
|
129
|
+
// before it is typing this read already settled.
|
|
130
|
+
const escapeAt = rest.lastIndexOf('\u001b');
|
|
131
|
+
const candidate = escapeAt === -1 ? '' : rest.slice(escapeAt);
|
|
132
|
+
const tail = candidate.length <= PARTIAL_REPORT_MAX && PARTIAL_REPORT.test(candidate) ? candidate : '';
|
|
133
|
+
held = tail;
|
|
134
|
+
return { forward: forward + rest.slice(0, rest.length - tail.length), sizes };
|
|
135
|
+
},
|
|
136
|
+
flush() {
|
|
137
|
+
const tail = held;
|
|
138
|
+
held = '';
|
|
139
|
+
return tail;
|
|
140
|
+
},
|
|
141
|
+
/** Is a run held that could still grow into a report? */
|
|
142
|
+
get pending() {
|
|
143
|
+
return held !== '';
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=display-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display-mode.js","sourceRoot":"","sources":["../src/display-mode.ts"],"names":[],"mappings":"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"}
|