@agi-fans/dsh-tui 0.7.0 → 0.9.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.
- package/lib/CHANGELOG.md +44 -1
- package/lib/chrome/box.d.ts +0 -7
- package/lib/chrome/box.js +3 -22
- package/lib/chrome/box.js.map +1 -1
- package/lib/chrome/code-highlight.d.ts +45 -0
- package/lib/chrome/code-highlight.js +155 -0
- package/lib/chrome/code-highlight.js.map +1 -0
- package/lib/chrome/diff-render.d.ts +3 -1
- package/lib/chrome/diff-render.js +73 -9
- package/lib/chrome/diff-render.js.map +1 -1
- package/lib/chrome/main-screen-renderer.d.ts +55 -0
- package/lib/chrome/main-screen-renderer.js +343 -0
- package/lib/chrome/main-screen-renderer.js.map +1 -0
- package/lib/chrome/markdown.d.ts +3 -6
- package/lib/chrome/markdown.js +5 -59
- package/lib/chrome/markdown.js.map +1 -1
- package/lib/chrome/md-style.d.ts +31 -0
- package/lib/chrome/md-style.js +58 -0
- package/lib/chrome/md-style.js.map +1 -0
- package/lib/chrome/renderer.d.ts +8 -31
- package/lib/chrome/renderer.js.map +1 -1
- package/lib/chrome/welcome-tips.js +2 -2
- package/lib/chrome/welcome-tips.js.map +1 -1
- package/lib/chrome/width.d.ts +15 -0
- package/lib/chrome/width.js +83 -0
- package/lib/chrome/width.js.map +1 -1
- package/lib/commands/auth.d.ts +2 -1
- package/lib/commands/auth.js +318 -38
- package/lib/commands/auth.js.map +1 -1
- package/lib/commands/permission.js +1 -6
- package/lib/commands/permission.js.map +1 -1
- package/lib/definition.d.ts +1 -1
- package/lib/input/keys.d.ts +1 -28
- package/lib/input/keys.js +15 -31
- package/lib/input/keys.js.map +1 -1
- package/lib/runtime/provider-local.d.ts +7 -5
- package/lib/runtime/provider-local.js +134 -208
- package/lib/runtime/provider-local.js.map +1 -1
- package/lib/session/authorization-interaction.d.ts +12 -0
- package/lib/session/authorization-interaction.js +70 -0
- package/lib/session/authorization-interaction.js.map +1 -0
- package/lib/session/session-controller.d.ts +8 -4
- package/lib/session/session-controller.js +13 -12
- package/lib/session/session-controller.js.map +1 -1
- package/lib/views/autocomplete.d.ts +0 -2
- package/lib/views/autocomplete.js +0 -8
- package/lib/views/autocomplete.js.map +1 -1
- package/lib/views/copy-selector.d.ts +0 -4
- package/lib/views/copy-selector.js +0 -17
- package/lib/views/copy-selector.js.map +1 -1
- package/lib/views/event-views.d.ts +3 -16
- package/lib/views/event-views.js +127 -93
- package/lib/views/event-views.js.map +1 -1
- package/lib/views/history-search.d.ts +0 -5
- package/lib/views/history-search.js +0 -16
- package/lib/views/history-search.js.map +1 -1
- package/lib/views/hotkeys.js +0 -1
- package/lib/views/hotkeys.js.map +1 -1
- package/lib/views/prompt-selector.d.ts +0 -5
- package/lib/views/prompt-selector.js +0 -13
- package/lib/views/prompt-selector.js.map +1 -1
- package/lib/views/settings-list.d.ts +0 -5
- package/lib/views/settings-list.js +0 -23
- package/lib/views/settings-list.js.map +1 -1
- package/package.json +29 -27
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main-screen renderer.
|
|
3
|
+
*
|
|
4
|
+
* The terminal owns native scrollback. This renderer owns only the current
|
|
5
|
+
* screen and a logical boundary for rows already frozen above it. Routine
|
|
6
|
+
* updates treat native history as append-only. Explicit transcript epochs
|
|
7
|
+
* clear it once and replay the replacement frame from a clean origin.
|
|
8
|
+
*
|
|
9
|
+
* Finalized rows cross the boundary by being painted at the top of the screen
|
|
10
|
+
* immediately before a newline scrolls them into history. Pending rows remain
|
|
11
|
+
* in the mutable screen tail. A terminal height change is the one exception:
|
|
12
|
+
* the terminal itself can move visible rows across the scrollback boundary, so
|
|
13
|
+
* the renderer adopts that new physical boundary instead of emitting the rows
|
|
14
|
+
* again.
|
|
15
|
+
*
|
|
16
|
+
* reset() repairs the visible screen without replaying history. A logical
|
|
17
|
+
* conversation replacement must call startEpoch() so stale native history is
|
|
18
|
+
* cleared before the replacement transcript is replayed.
|
|
19
|
+
*
|
|
20
|
+
* The renderer never enables mouse tracking (1000/1006) and wraps every paint
|
|
21
|
+
* in one DEC 2026 synchronized write.
|
|
22
|
+
* @module @agi-fans/dsh-tui
|
|
23
|
+
*/
|
|
24
|
+
import { type Frame, type RenderSink } from './renderer.ts';
|
|
25
|
+
export interface MainScreenRendererOptions {
|
|
26
|
+
/** Terminal height in rows. */
|
|
27
|
+
height: number;
|
|
28
|
+
/** Terminal width in columns. */
|
|
29
|
+
width?: number;
|
|
30
|
+
/** Wrap the paint in synchronized output (DEC 2026). */
|
|
31
|
+
synchronized?: boolean;
|
|
32
|
+
/** Whether explicit transcript replacement may erase native scrollback. */
|
|
33
|
+
clearScrollback?: boolean;
|
|
34
|
+
/** Borrow the alternate buffer for transient full-screen surfaces. */
|
|
35
|
+
alternateScreenOverlays?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface EpochOptions {
|
|
38
|
+
/** Full freezes the restored snapshot; pinned preserves its mutable suffix. */
|
|
39
|
+
replay?: 'full' | 'pinned';
|
|
40
|
+
}
|
|
41
|
+
/** Render frames into the terminal main screen while preserving native history. */
|
|
42
|
+
export declare class MainScreenRenderer {
|
|
43
|
+
#private;
|
|
44
|
+
constructor(sink: RenderSink, options: MainScreenRendererOptions);
|
|
45
|
+
/** Record terminal geometry; the terminal has already performed the resize. */
|
|
46
|
+
resize(width: number, height: number): void;
|
|
47
|
+
/** Repaint the current viewport without replaying frozen history. */
|
|
48
|
+
reset(): void;
|
|
49
|
+
/** Replace native history with a new logical transcript on the next paint. */
|
|
50
|
+
startEpoch(options?: EpochOptions): void;
|
|
51
|
+
/** Put the cursor below the UI before terminal ownership is released. */
|
|
52
|
+
finish(): void;
|
|
53
|
+
/** Render a frame, appending only finalized rows during a stable geometry epoch. */
|
|
54
|
+
render(frame: Frame): void;
|
|
55
|
+
}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main-screen renderer.
|
|
3
|
+
*
|
|
4
|
+
* The terminal owns native scrollback. This renderer owns only the current
|
|
5
|
+
* screen and a logical boundary for rows already frozen above it. Routine
|
|
6
|
+
* updates treat native history as append-only. Explicit transcript epochs
|
|
7
|
+
* clear it once and replay the replacement frame from a clean origin.
|
|
8
|
+
*
|
|
9
|
+
* Finalized rows cross the boundary by being painted at the top of the screen
|
|
10
|
+
* immediately before a newline scrolls them into history. Pending rows remain
|
|
11
|
+
* in the mutable screen tail. A terminal height change is the one exception:
|
|
12
|
+
* the terminal itself can move visible rows across the scrollback boundary, so
|
|
13
|
+
* the renderer adopts that new physical boundary instead of emitting the rows
|
|
14
|
+
* again.
|
|
15
|
+
*
|
|
16
|
+
* reset() repairs the visible screen without replaying history. A logical
|
|
17
|
+
* conversation replacement must call startEpoch() so stale native history is
|
|
18
|
+
* cleared before the replacement transcript is replayed.
|
|
19
|
+
*
|
|
20
|
+
* The renderer never enables mouse tracking (1000/1006) and wraps every paint
|
|
21
|
+
* in one DEC 2026 synchronized write.
|
|
22
|
+
* @module @agi-fans/dsh-tui
|
|
23
|
+
*/
|
|
24
|
+
import { sanitizeDisplayLine } from "./renderer.js";
|
|
25
|
+
const DISABLE_AUTOWRAP = '\x1b[?7l';
|
|
26
|
+
const ENABLE_AUTOWRAP = '\x1b[?7h';
|
|
27
|
+
const SYNC_OUTPUT_BEGIN = '\x1b[?2026h';
|
|
28
|
+
const SYNC_OUTPUT_END = '\x1b[?2026l';
|
|
29
|
+
const HIDE_CURSOR = '\x1b[?25l';
|
|
30
|
+
const SHOW_CURSOR = '\x1b[?25h';
|
|
31
|
+
const ENTER_ALT_SCREEN = '\x1b[?1049h';
|
|
32
|
+
const EXIT_ALT_SCREEN = '\x1b[?1049l';
|
|
33
|
+
const CLEAR_SCROLLBACK = '\x1b[3J';
|
|
34
|
+
const CLEAR_SCREEN = '\x1b[2J\x1b[H';
|
|
35
|
+
const CLEAR_LINE = '\x1b[2K';
|
|
36
|
+
function csi(row, column) {
|
|
37
|
+
return `\x1b[${Math.max(1, row + 1)};${Math.max(1, column + 1)}H`;
|
|
38
|
+
}
|
|
39
|
+
/** Render frames into the terminal main screen while preserving native history. */
|
|
40
|
+
export class MainScreenRenderer {
|
|
41
|
+
#sink;
|
|
42
|
+
#synchronized;
|
|
43
|
+
#canClearScrollback;
|
|
44
|
+
#alternateScreenOverlays;
|
|
45
|
+
#width;
|
|
46
|
+
#height;
|
|
47
|
+
#resize;
|
|
48
|
+
#hasFrame = false;
|
|
49
|
+
#reanchor = false;
|
|
50
|
+
#newEpoch = false;
|
|
51
|
+
#fullReplayOnNextEpoch = true;
|
|
52
|
+
#clearScrollbackOnNextRender = false;
|
|
53
|
+
#adoptPhysicalAfterTransient = false;
|
|
54
|
+
/** First logical row not frozen above the screen in the current epoch. */
|
|
55
|
+
#physical = 0;
|
|
56
|
+
/** Exact visible rows expected on the physical screen. */
|
|
57
|
+
#screen;
|
|
58
|
+
#transient = false;
|
|
59
|
+
#altActive = false;
|
|
60
|
+
#altScreen;
|
|
61
|
+
#cursorRow = 0;
|
|
62
|
+
#cursorCol = 0;
|
|
63
|
+
#cursorVisible = true;
|
|
64
|
+
constructor(sink, options) {
|
|
65
|
+
this.#sink = sink;
|
|
66
|
+
this.#width = options.width ?? 0;
|
|
67
|
+
this.#height = Math.max(1, options.height);
|
|
68
|
+
this.#screen = this.#blankScreen();
|
|
69
|
+
this.#altScreen = this.#blankScreen();
|
|
70
|
+
this.#synchronized = options.synchronized === true;
|
|
71
|
+
this.#canClearScrollback = options.clearScrollback !== false;
|
|
72
|
+
this.#alternateScreenOverlays = options.alternateScreenOverlays === true;
|
|
73
|
+
}
|
|
74
|
+
/** Record terminal geometry; the terminal has already performed the resize. */
|
|
75
|
+
resize(width, height) {
|
|
76
|
+
const nextHeight = Math.max(1, height);
|
|
77
|
+
if (width === this.#width && nextHeight === this.#height)
|
|
78
|
+
return;
|
|
79
|
+
const transition = this.#resize ?? { oldHeight: this.#height, widthChanged: false };
|
|
80
|
+
transition.widthChanged ||= width !== this.#width;
|
|
81
|
+
this.#resize = transition;
|
|
82
|
+
this.#width = width;
|
|
83
|
+
this.#height = nextHeight;
|
|
84
|
+
}
|
|
85
|
+
/** Repaint the current viewport without replaying frozen history. */
|
|
86
|
+
reset() {
|
|
87
|
+
this.#reanchor = true;
|
|
88
|
+
}
|
|
89
|
+
/** Replace native history with a new logical transcript on the next paint. */
|
|
90
|
+
startEpoch(options = {}) {
|
|
91
|
+
this.#newEpoch = true;
|
|
92
|
+
this.#fullReplayOnNextEpoch = options.replay !== 'pinned';
|
|
93
|
+
this.#clearScrollbackOnNextRender = true;
|
|
94
|
+
this.#reanchor = true;
|
|
95
|
+
this.#adoptPhysicalAfterTransient = false;
|
|
96
|
+
}
|
|
97
|
+
/** Put the cursor below the UI before terminal ownership is released. */
|
|
98
|
+
finish() {
|
|
99
|
+
const targetRow = Math.max(0, this.#height - 1);
|
|
100
|
+
let out = '';
|
|
101
|
+
if (this.#altActive) {
|
|
102
|
+
out += EXIT_ALT_SCREEN;
|
|
103
|
+
this.#altActive = false;
|
|
104
|
+
this.#altScreen = this.#blankScreen();
|
|
105
|
+
}
|
|
106
|
+
if (!this.#cursorVisible)
|
|
107
|
+
out += SHOW_CURSOR;
|
|
108
|
+
out += csi(targetRow, 0);
|
|
109
|
+
if (out !== '')
|
|
110
|
+
this.#sink.write(out);
|
|
111
|
+
this.#cursorRow = targetRow;
|
|
112
|
+
this.#cursorCol = 0;
|
|
113
|
+
this.#cursorVisible = true;
|
|
114
|
+
}
|
|
115
|
+
/** Render a frame, appending only finalized rows during a stable geometry epoch. */
|
|
116
|
+
render(frame) {
|
|
117
|
+
const next = frame.lines.map(line => sanitizeDisplayLine(String(line)));
|
|
118
|
+
const liveStart = Math.max(0, Math.min(frame.liveStart ?? 0, next.length));
|
|
119
|
+
const livePinned = frame.livePinned !== false;
|
|
120
|
+
const cursor = frame.cursor ?? { row: next.length, column: 0 };
|
|
121
|
+
const cursorVisible = frame.cursorVisible !== false;
|
|
122
|
+
const paint = liveStart === 0
|
|
123
|
+
? this.#paintTransient(next, cursor, cursorVisible)
|
|
124
|
+
: this.#paintFollow(next, liveStart, livePinned, cursor, cursorVisible);
|
|
125
|
+
if (paint !== '')
|
|
126
|
+
this.#sink.write(paint);
|
|
127
|
+
}
|
|
128
|
+
#paintTransient(next, cursor, cursorVisible) {
|
|
129
|
+
const target = this.#target(next, 0, 'top');
|
|
130
|
+
if (this.#alternateScreenOverlays) {
|
|
131
|
+
const clear = !this.#altActive || this.#resize !== undefined;
|
|
132
|
+
let body = this.#altActive ? '' : ENTER_ALT_SCREEN;
|
|
133
|
+
body += this.#paintScreen(target.rows, clear ? this.#blankScreen() : this.#altScreen, clear);
|
|
134
|
+
const targetRow = this.#screenRow(cursor.row, target, next.length);
|
|
135
|
+
body += csi(targetRow, cursor.column);
|
|
136
|
+
body += cursorVisible ? SHOW_CURSOR : HIDE_CURSOR;
|
|
137
|
+
this.#altActive = true;
|
|
138
|
+
this.#altScreen = target.rows;
|
|
139
|
+
this.#cursorVisible = cursorVisible;
|
|
140
|
+
return this.#wrap(body);
|
|
141
|
+
}
|
|
142
|
+
const resized = this.#takeResizeBaseline();
|
|
143
|
+
const body = this.#paintScreen(target.rows, resized.rows, this.#reanchor || resized.clear);
|
|
144
|
+
this.#reanchor = false;
|
|
145
|
+
this.#transient = true;
|
|
146
|
+
return this.#finishPaint(body, target, next.length, cursor, cursorVisible);
|
|
147
|
+
}
|
|
148
|
+
#paintFollow(next, liveStart, livePinned, cursor, cursorVisible) {
|
|
149
|
+
const exitAlt = this.#altActive ? EXIT_ALT_SCREEN : '';
|
|
150
|
+
if (this.#altActive) {
|
|
151
|
+
this.#altActive = false;
|
|
152
|
+
this.#altScreen = this.#blankScreen();
|
|
153
|
+
}
|
|
154
|
+
const viewStart = Math.max(0, next.length - this.#height);
|
|
155
|
+
const candidatePhysical = livePinned ? Math.min(liveStart, viewStart) : viewStart;
|
|
156
|
+
let effectiveStart = viewStart;
|
|
157
|
+
let target = this.#target(next, effectiveStart, 'bottom');
|
|
158
|
+
let body = '';
|
|
159
|
+
if (!this.#hasFrame || this.#newEpoch) {
|
|
160
|
+
// An explicit replacement follows ED3, so it must rebuild the complete
|
|
161
|
+
// logical frame. Durable logs can end with an orphaned streaming/tool
|
|
162
|
+
// block; applying the ordinary pending seam here would silently omit its
|
|
163
|
+
// off-screen middle from the restored transcript.
|
|
164
|
+
const replayPhysical = this.#newEpoch && this.#fullReplayOnNextEpoch ? viewStart : candidatePhysical;
|
|
165
|
+
body = this.#paintFlush(next, 0, replayPhysical, viewStart, true);
|
|
166
|
+
this.#physical = replayPhysical;
|
|
167
|
+
this.#newEpoch = false;
|
|
168
|
+
this.#fullReplayOnNextEpoch = true;
|
|
169
|
+
this.#resize = undefined;
|
|
170
|
+
}
|
|
171
|
+
else if (this.#resize !== undefined) {
|
|
172
|
+
const transition = this.#resize;
|
|
173
|
+
const baseline = this.#resizedScreen(transition.oldHeight);
|
|
174
|
+
body = this.#paintScreen(target.rows, baseline, transition.widthChanged);
|
|
175
|
+
// The terminal has already moved rows between screen and scrollback.
|
|
176
|
+
// Adopt that physical boundary rather than replaying those rows.
|
|
177
|
+
this.#physical = viewStart;
|
|
178
|
+
this.#resize = undefined;
|
|
179
|
+
}
|
|
180
|
+
else if (this.#reanchor) {
|
|
181
|
+
if (candidatePhysical > this.#physical) {
|
|
182
|
+
body = this.#paintFlush(next, this.#physical, candidatePhysical, viewStart, true);
|
|
183
|
+
this.#physical = candidatePhysical;
|
|
184
|
+
}
|
|
185
|
+
else if (next.length <= this.#physical) {
|
|
186
|
+
body = this.#paintFlush(next, 0, candidatePhysical, viewStart, true);
|
|
187
|
+
this.#physical = candidatePhysical;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
effectiveStart = Math.max(this.#physical, viewStart);
|
|
191
|
+
target = this.#target(next, effectiveStart, 'bottom');
|
|
192
|
+
body = this.#paintScreen(target.rows, this.#screen, true);
|
|
193
|
+
}
|
|
194
|
+
this.#reanchor = false;
|
|
195
|
+
}
|
|
196
|
+
else if (this.#transient) {
|
|
197
|
+
if (this.#adoptPhysicalAfterTransient) {
|
|
198
|
+
body = this.#paintScreen(target.rows, this.#screen, true);
|
|
199
|
+
this.#physical = viewStart;
|
|
200
|
+
this.#adoptPhysicalAfterTransient = false;
|
|
201
|
+
}
|
|
202
|
+
else if (candidatePhysical > this.#physical) {
|
|
203
|
+
body = this.#paintFlush(next, this.#physical, candidatePhysical, viewStart, false);
|
|
204
|
+
this.#physical = candidatePhysical;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
effectiveStart = candidatePhysical < this.#physical && next.length > this.#physical
|
|
208
|
+
? Math.max(this.#physical, viewStart)
|
|
209
|
+
: viewStart;
|
|
210
|
+
target = this.#target(next, effectiveStart, 'bottom');
|
|
211
|
+
body = this.#paintScreen(target.rows, this.#screen, true);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else if (next.length <= this.#physical) {
|
|
215
|
+
// A logical clear/replace that was not explicitly signalled still needs
|
|
216
|
+
// an independent index space. Keep old history and append the new epoch.
|
|
217
|
+
body = this.#paintFlush(next, 0, candidatePhysical, viewStart, true);
|
|
218
|
+
this.#physical = candidatePhysical;
|
|
219
|
+
}
|
|
220
|
+
else if (candidatePhysical > this.#physical) {
|
|
221
|
+
body = this.#paintFlush(next, this.#physical, candidatePhysical, viewStart, false);
|
|
222
|
+
this.#physical = candidatePhysical;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
if (candidatePhysical < this.#physical)
|
|
226
|
+
effectiveStart = Math.max(this.#physical, viewStart);
|
|
227
|
+
target = this.#target(next, effectiveStart, 'bottom');
|
|
228
|
+
body = this.#paintScreen(target.rows, this.#screen, false);
|
|
229
|
+
}
|
|
230
|
+
this.#transient = false;
|
|
231
|
+
return this.#finishPaint(exitAlt + body, target, next.length, cursor, cursorVisible);
|
|
232
|
+
}
|
|
233
|
+
/** Emit finalized rows followed by the bounded live tail. */
|
|
234
|
+
#paintFlush(next, start, committedEnd, viewStart, clearScreen) {
|
|
235
|
+
const rows = [
|
|
236
|
+
...next.slice(start, committedEnd),
|
|
237
|
+
...next.slice(viewStart, viewStart + this.#height),
|
|
238
|
+
];
|
|
239
|
+
let out = clearScreen ? CLEAR_SCREEN : csi(0, 0);
|
|
240
|
+
if (rows.length < this.#height)
|
|
241
|
+
out += csi(this.#height - rows.length, 0);
|
|
242
|
+
for (let i = 0; i < rows.length; i += 1) {
|
|
243
|
+
if (i > 0)
|
|
244
|
+
out += '\r\n';
|
|
245
|
+
// EL is required before a shorter final row scrolls into history.
|
|
246
|
+
out += CLEAR_LINE + (rows[i] ?? '');
|
|
247
|
+
}
|
|
248
|
+
return out;
|
|
249
|
+
}
|
|
250
|
+
#paintScreen(next, old, clear) {
|
|
251
|
+
return (clear ? CLEAR_SCREEN : '') + this.#paintDiff(next, clear ? this.#blankScreen() : old);
|
|
252
|
+
}
|
|
253
|
+
#paintDiff(next, old) {
|
|
254
|
+
let out = '';
|
|
255
|
+
let runStart = -1;
|
|
256
|
+
let runEnd = -1;
|
|
257
|
+
for (let row = 0; row < this.#height; row += 1) {
|
|
258
|
+
const before = old[row] ?? '';
|
|
259
|
+
const after = next[row] ?? '';
|
|
260
|
+
if (before !== after) {
|
|
261
|
+
if (runStart === -1)
|
|
262
|
+
runStart = row;
|
|
263
|
+
runEnd = row;
|
|
264
|
+
}
|
|
265
|
+
else if (runStart !== -1) {
|
|
266
|
+
out += this.#writeRun(next, runStart, runEnd);
|
|
267
|
+
runStart = -1;
|
|
268
|
+
runEnd = -1;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (runStart !== -1)
|
|
272
|
+
out += this.#writeRun(next, runStart, runEnd);
|
|
273
|
+
return out;
|
|
274
|
+
}
|
|
275
|
+
#writeRun(lines, start, end) {
|
|
276
|
+
let out = csi(start, 0);
|
|
277
|
+
for (let row = start; row <= end; row += 1) {
|
|
278
|
+
if (row > start)
|
|
279
|
+
out += '\r\n';
|
|
280
|
+
out += CLEAR_LINE + (lines[row] ?? '');
|
|
281
|
+
}
|
|
282
|
+
return out;
|
|
283
|
+
}
|
|
284
|
+
#target(next, start, anchor) {
|
|
285
|
+
const content = next.slice(start, start + this.#height).map(line => line ?? '');
|
|
286
|
+
const offset = anchor === 'bottom' ? Math.max(0, this.#height - content.length) : 0;
|
|
287
|
+
const rows = this.#blankScreen();
|
|
288
|
+
for (let i = 0; i < content.length; i += 1)
|
|
289
|
+
rows[offset + i] = content[i] ?? '';
|
|
290
|
+
return { rows, start, offset };
|
|
291
|
+
}
|
|
292
|
+
#takeResizeBaseline() {
|
|
293
|
+
if (this.#resize === undefined)
|
|
294
|
+
return { rows: this.#screen, clear: false };
|
|
295
|
+
const transition = this.#resize;
|
|
296
|
+
this.#resize = undefined;
|
|
297
|
+
this.#adoptPhysicalAfterTransient = true;
|
|
298
|
+
return {
|
|
299
|
+
rows: transition.widthChanged ? this.#blankScreen() : this.#resizedScreen(transition.oldHeight),
|
|
300
|
+
clear: transition.widthChanged,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
#resizedScreen(oldHeight) {
|
|
304
|
+
if (this.#height < oldHeight)
|
|
305
|
+
return this.#screen.slice(oldHeight - this.#height);
|
|
306
|
+
if (this.#height > oldHeight) {
|
|
307
|
+
return [...Array.from({ length: this.#height - oldHeight }, () => ''), ...this.#screen];
|
|
308
|
+
}
|
|
309
|
+
return this.#screen.slice(0, this.#height);
|
|
310
|
+
}
|
|
311
|
+
#finishPaint(body, target, length, cursor, cursorVisible) {
|
|
312
|
+
const targetRow = this.#screenRow(cursor.row, target, length);
|
|
313
|
+
const targetCol = cursor.column;
|
|
314
|
+
const hide = !cursorVisible && this.#cursorVisible ? HIDE_CURSOR : '';
|
|
315
|
+
const show = cursorVisible && !this.#cursorVisible ? SHOW_CURSOR : '';
|
|
316
|
+
const moved = targetRow !== this.#cursorRow || targetCol !== this.#cursorCol;
|
|
317
|
+
const visibilityChanged = cursorVisible !== this.#cursorVisible;
|
|
318
|
+
const cursorOut = body !== '' || moved || visibilityChanged ? csi(targetRow, targetCol) : '';
|
|
319
|
+
const clearScrollback = this.#clearScrollbackOnNextRender && this.#canClearScrollback;
|
|
320
|
+
this.#clearScrollbackOnNextRender = false;
|
|
321
|
+
this.#cursorRow = targetRow;
|
|
322
|
+
this.#cursorCol = targetCol;
|
|
323
|
+
this.#cursorVisible = cursorVisible;
|
|
324
|
+
this.#screen = target.rows;
|
|
325
|
+
this.#hasFrame = true;
|
|
326
|
+
return this.#wrap((clearScrollback ? CLEAR_SCROLLBACK : '') + body + cursorOut + hide + show);
|
|
327
|
+
}
|
|
328
|
+
#screenRow(logicalRow, target, length) {
|
|
329
|
+
const clamped = Math.max(0, Math.min(Math.max(0, length - 1), logicalRow));
|
|
330
|
+
return Math.max(0, Math.min(this.#height - 1, target.offset + clamped - target.start));
|
|
331
|
+
}
|
|
332
|
+
#blankScreen() {
|
|
333
|
+
return Array.from({ length: this.#height }, () => '');
|
|
334
|
+
}
|
|
335
|
+
#wrap(payload) {
|
|
336
|
+
if (payload === '')
|
|
337
|
+
return '';
|
|
338
|
+
return this.#synchronized
|
|
339
|
+
? SYNC_OUTPUT_BEGIN + DISABLE_AUTOWRAP + payload + ENABLE_AUTOWRAP + SYNC_OUTPUT_END
|
|
340
|
+
: DISABLE_AUTOWRAP + payload + ENABLE_AUTOWRAP;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=main-screen-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main-screen-renderer.js","sourceRoot":"","sources":["../../src/chrome/main-screen-renderer.ts"],"names":[],"mappings":"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"}
|
package/lib/chrome/markdown.d.ts
CHANGED
|
@@ -3,12 +3,9 @@
|
|
|
3
3
|
* tokens with the TUI theme and wraps to display columns.
|
|
4
4
|
* @module @agi-fans/dsh-tui
|
|
5
5
|
*/
|
|
6
|
-
import { type Theme
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
color?: ThemeColor;
|
|
10
|
-
italic?: boolean;
|
|
11
|
-
}
|
|
6
|
+
import { type Theme } from './theme.ts';
|
|
7
|
+
import { type MarkdownStyle } from './md-style.ts';
|
|
8
|
+
export type { MarkdownStyle } from './md-style.ts';
|
|
12
9
|
/** Inline markdown: code, links, strike, bold, italic, math. */
|
|
13
10
|
export declare function renderInline(text: string, theme: Theme, style?: MarkdownStyle): string;
|
|
14
11
|
/**
|
package/lib/chrome/markdown.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Lexer, Marked } from 'marked';
|
|
7
7
|
import { BOX, SYMBOL } from "./theme.js";
|
|
8
|
+
import { highlightCodeLines } from "./code-highlight.js";
|
|
9
|
+
import { ink, openBase, paintBase, paintBold, paintFg, paintItalic, paintStrike } from "./md-style.js";
|
|
8
10
|
import { padToWidth, visibleWidth, wrapText } from "./width.js";
|
|
9
11
|
const MATH_SYMBOLS = {
|
|
10
12
|
alpha: 'α', beta: 'β', gamma: 'γ', delta: 'δ', theta: 'θ', lambda: 'λ', mu: 'μ',
|
|
@@ -118,47 +120,6 @@ function normalizeHtml(source) {
|
|
|
118
120
|
function prepare(source) {
|
|
119
121
|
return normalizeHtml(source).replaceAll('\r\n', '\n').replaceAll('\r', '\n');
|
|
120
122
|
}
|
|
121
|
-
function openBase(theme, style) {
|
|
122
|
-
if (!theme.colors || style === undefined)
|
|
123
|
-
return '';
|
|
124
|
-
return (style.italic === true ? '\x1b[3m' : '')
|
|
125
|
-
+ (style.color === undefined ? '' : theme.getFgAnsi(style.color));
|
|
126
|
-
}
|
|
127
|
-
/** Keep thinking traces on one dark ink so headings, code, and links do not light up. */
|
|
128
|
-
function ink(style, color) {
|
|
129
|
-
return style?.color === 'thinkingText' ? 'thinkingText' : color;
|
|
130
|
-
}
|
|
131
|
-
/** Paint one unstyled run so a later 39m cannot leak default ink. */
|
|
132
|
-
function paintBase(theme, text, style) {
|
|
133
|
-
if (text === '' || style === undefined || !theme.colors)
|
|
134
|
-
return text;
|
|
135
|
-
let out = text;
|
|
136
|
-
if (style.color !== undefined)
|
|
137
|
-
out = theme.fg(style.color, out);
|
|
138
|
-
if (style.italic === true)
|
|
139
|
-
out = theme.italic(out);
|
|
140
|
-
return out;
|
|
141
|
-
}
|
|
142
|
-
function paintFg(theme, color, text, style) {
|
|
143
|
-
if (!theme.colors)
|
|
144
|
-
return text;
|
|
145
|
-
return theme.getFgAnsi(color) + text + '\x1b[39m' + openBase(theme, style);
|
|
146
|
-
}
|
|
147
|
-
function paintBold(theme, text, style) {
|
|
148
|
-
if (!theme.colors)
|
|
149
|
-
return text;
|
|
150
|
-
return `\x1b[1m${text}\x1b[22m` + openBase(theme, style);
|
|
151
|
-
}
|
|
152
|
-
function paintItalic(theme, text, style) {
|
|
153
|
-
if (!theme.colors)
|
|
154
|
-
return text;
|
|
155
|
-
return `\x1b[3m${text}\x1b[23m` + openBase(theme, style);
|
|
156
|
-
}
|
|
157
|
-
function paintStrike(theme, text, style) {
|
|
158
|
-
if (!theme.colors)
|
|
159
|
-
return text;
|
|
160
|
-
return `\x1b[9m${text}\x1b[29m` + openBase(theme, style);
|
|
161
|
-
}
|
|
162
123
|
function isProseCodespan(text) {
|
|
163
124
|
const words = text.trim().split(/\s+/u).filter(Boolean);
|
|
164
125
|
return words.length >= 4 || (words.length >= 2 && /[,;]/.test(text));
|
|
@@ -170,22 +131,6 @@ function renderMath(value, theme, style) {
|
|
|
170
131
|
.replace(/_\{([^}]+)\}/gu, '₍$1₎');
|
|
171
132
|
return paintFg(theme, ink(style, 'mdCode'), normalized, style);
|
|
172
133
|
}
|
|
173
|
-
function highlightCode(row, language, theme, style) {
|
|
174
|
-
if (!theme.colors || language === '')
|
|
175
|
-
return paintFg(theme, ink(style, 'mdCodeBlock'), row, style);
|
|
176
|
-
const supported = /^(?:js|jsx|ts|tsx|javascript|typescript|json|python|py|bash|sh|shell|rust|go|java|css|html)$/u.test(language);
|
|
177
|
-
if (!supported)
|
|
178
|
-
return paintFg(theme, ink(style, 'mdCodeBlock'), row, style);
|
|
179
|
-
return row.split(/(\s+|\b)/u).map(token => {
|
|
180
|
-
if (/^(?:const|let|var|function|class|interface|type|return|if|else|for|while|async|await|import|export|from|def|fn|struct|package|func|true|false|null|undefined)$/u.test(token)) {
|
|
181
|
-
return paintFg(theme, ink(style, 'mdKeyword'), token, style);
|
|
182
|
-
}
|
|
183
|
-
if (/^(?:\d+(?:\.\d+)?|"[^"]*"|'[^']*')$/u.test(token)) {
|
|
184
|
-
return paintFg(theme, ink(style, 'mdCodeBlock'), token, style);
|
|
185
|
-
}
|
|
186
|
-
return paintBase(theme, token, style);
|
|
187
|
-
}).join('');
|
|
188
|
-
}
|
|
189
134
|
function mermaidEndpoint(raw) {
|
|
190
135
|
const text = raw.trim();
|
|
191
136
|
const labeled = /^(?:[\w.-]*)\[([^\]]+)\]$/u.exec(text)
|
|
@@ -413,8 +358,9 @@ function renderCode(token, theme, width, style) {
|
|
|
413
358
|
lines.push(...renderMermaid(rows, theme, width, style));
|
|
414
359
|
}
|
|
415
360
|
else {
|
|
416
|
-
|
|
417
|
-
|
|
361
|
+
const highlighted = highlightCodeLines(rows, lang, theme, style);
|
|
362
|
+
for (let i = 0; i < rows.length; i += 1) {
|
|
363
|
+
const body = highlighted[i] ?? '';
|
|
418
364
|
lines.push(...wrapStyled(body === '' ? ' ' : ' ' + body, width));
|
|
419
365
|
}
|
|
420
366
|
}
|