@thegitai/cli 1.0.0-preview.14 → 1.0.0-preview.15
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.
|
@@ -61,6 +61,13 @@ function normalizeChildMessage(raw) {
|
|
|
61
61
|
deltaLines: Number(raw.deltaLines ?? raw.delta_lines ?? 0),
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
+
if (raw.kind === 'transcriptScrollTo') {
|
|
65
|
+
return {
|
|
66
|
+
op: 'event',
|
|
67
|
+
kind: 'transcriptScrollTo',
|
|
68
|
+
offset: Number(raw.offset ?? 0),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
64
71
|
if (raw.kind !== 'key') {
|
|
65
72
|
return null;
|
|
66
73
|
}
|
|
@@ -341,6 +341,26 @@ export function renderTranscriptEntryLines(entry, width) {
|
|
|
341
341
|
}
|
|
342
342
|
return lines;
|
|
343
343
|
}
|
|
344
|
+
const transcriptEntryLineCache = new WeakMap();
|
|
345
|
+
const MAX_CACHED_TRANSCRIPT_WIDTHS = 2;
|
|
346
|
+
function cachedTranscriptEntryLines(entry, width) {
|
|
347
|
+
let byWidth = transcriptEntryLineCache.get(entry);
|
|
348
|
+
if (!byWidth) {
|
|
349
|
+
byWidth = new Map();
|
|
350
|
+
transcriptEntryLineCache.set(entry, byWidth);
|
|
351
|
+
}
|
|
352
|
+
const cached = byWidth.get(width);
|
|
353
|
+
if (cached)
|
|
354
|
+
return cached;
|
|
355
|
+
const lines = renderTranscriptEntryLines(entry, width);
|
|
356
|
+
if (byWidth.size >= MAX_CACHED_TRANSCRIPT_WIDTHS) {
|
|
357
|
+
const oldest = byWidth.keys().next().value;
|
|
358
|
+
if (oldest !== undefined)
|
|
359
|
+
byWidth.delete(oldest);
|
|
360
|
+
}
|
|
361
|
+
byWidth.set(width, lines);
|
|
362
|
+
return lines;
|
|
363
|
+
}
|
|
344
364
|
function renderDiffPreviewLines(preview, width, maxDiffLines = TRANSCRIPT_DIFF_PREVIEW_LINES) {
|
|
345
365
|
return [
|
|
346
366
|
plainLine(` Added ${preview.added} line${preview.added === 1 ? '' : 's'}, removed ${preview.removed} line${preview.removed === 1 ? '' : 's'}`, { color: 'gray' }),
|
|
@@ -1154,14 +1174,18 @@ function sliceTranscriptLines(lines, maxLines, scrollOffset) {
|
|
|
1154
1174
|
export function buildTuiFrame(state, cols, rows, spinnerFrame, elapsedSeconds, nowMs = 0) {
|
|
1155
1175
|
const contentWidth = Math.max(20, Math.floor(cols * 0.95) - 2);
|
|
1156
1176
|
const gutter = Math.max(Math.floor((cols - contentWidth) / 2), 0);
|
|
1157
|
-
const
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1177
|
+
const buildTranscriptLines = (wrapWidth) => {
|
|
1178
|
+
const blocks = state.transcript.map((entry) => cachedTranscriptEntryLines(entry, wrapWidth));
|
|
1179
|
+
const lines = [];
|
|
1180
|
+
blocks.forEach((block, index) => {
|
|
1181
|
+
if (index > 0) {
|
|
1182
|
+
lines.push(plainLine(''));
|
|
1183
|
+
}
|
|
1184
|
+
lines.push(...block);
|
|
1185
|
+
});
|
|
1186
|
+
return lines;
|
|
1187
|
+
};
|
|
1188
|
+
let transcriptLines = buildTranscriptLines(contentWidth);
|
|
1165
1189
|
const sections = [];
|
|
1166
1190
|
const liveLines = buildLiveLines(state, contentWidth, spinnerFrame, elapsedSeconds, nowMs);
|
|
1167
1191
|
if (liveLines.length > 0) {
|
|
@@ -1213,7 +1237,11 @@ export function buildTuiFrame(state, cols, rows, spinnerFrame, elapsedSeconds, n
|
|
|
1213
1237
|
? 0
|
|
1214
1238
|
: 4;
|
|
1215
1239
|
const transcriptBudget = Math.max(1, rows - reservedLines - composerReserve - 1);
|
|
1216
|
-
|
|
1240
|
+
let transcriptScrollLimit = Math.max(0, transcriptLines.length - transcriptBudget);
|
|
1241
|
+
if (transcriptScrollLimit > 0 && contentWidth > 2) {
|
|
1242
|
+
transcriptLines = buildTranscriptLines(contentWidth - 2);
|
|
1243
|
+
transcriptScrollLimit = Math.max(0, transcriptLines.length - transcriptBudget);
|
|
1244
|
+
}
|
|
1217
1245
|
const transcriptScrollOffset = Math.min(Math.max(state.transcriptScrollOffset, 0), transcriptScrollLimit);
|
|
1218
1246
|
sections.unshift({
|
|
1219
1247
|
kind: 'transcript',
|
|
@@ -275,9 +275,9 @@ function wrapInlineToLines(text, width, bodyColor, prefix = '') {
|
|
|
275
275
|
};
|
|
276
276
|
const appendSpan = (part) => {
|
|
277
277
|
let current = rows[rows.length - 1];
|
|
278
|
-
const limit = safeWidth - (rows.length === 1 && indent ? displayWidth(prefix) : 0);
|
|
279
278
|
let remaining = part.text;
|
|
280
279
|
while (remaining.length > 0) {
|
|
280
|
+
const limit = safeWidth - (rows.length === 1 && indent ? displayWidth(prefix) : 0);
|
|
281
281
|
const room = limit - rowWidth;
|
|
282
282
|
if (room <= 0) {
|
|
283
283
|
startRow();
|
|
@@ -291,8 +291,17 @@ function wrapInlineToLines(text, width, bodyColor, prefix = '') {
|
|
|
291
291
|
remaining = '';
|
|
292
292
|
break;
|
|
293
293
|
}
|
|
294
|
+
if (rowWidth > 0) {
|
|
295
|
+
if (/^\s+$/.test(remaining)) {
|
|
296
|
+
remaining = '';
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
startRow();
|
|
300
|
+
current = rows[rows.length - 1];
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
294
303
|
const head = sliceToWidth(remaining, room);
|
|
295
|
-
if (displayWidth(head) > room && current.length > 0) {
|
|
304
|
+
if (!head || (displayWidth(head) > room && current.length > 0)) {
|
|
296
305
|
startRow();
|
|
297
306
|
current = rows[rows.length - 1];
|
|
298
307
|
continue;
|
|
@@ -114,6 +114,16 @@ function scrollTranscript(store, handlers, delta) {
|
|
|
114
114
|
};
|
|
115
115
|
});
|
|
116
116
|
}
|
|
117
|
+
function scrollTranscriptTo(store, handlers, offset) {
|
|
118
|
+
store.update((current) => {
|
|
119
|
+
const limit = handlers.getTranscriptScrollLimit?.() ??
|
|
120
|
+
current.transcript.reduce((total, entry) => total + 2 + (entry.body ? entry.body.split('\n').length : 0), 0);
|
|
121
|
+
return {
|
|
122
|
+
...current,
|
|
123
|
+
transcriptScrollOffset: Math.max(0, Math.min(Math.trunc(offset), limit)),
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
}
|
|
117
127
|
function scrollApprovalPreview(store, handlers, delta) {
|
|
118
128
|
if (delta === 0)
|
|
119
129
|
return;
|
|
@@ -182,6 +192,10 @@ export function handleShellKeyEvent(store, handlers, event) {
|
|
|
182
192
|
scrollTranscript(store, handlers, Math.trunc(event.deltaLines));
|
|
183
193
|
return;
|
|
184
194
|
}
|
|
195
|
+
if (event.kind === 'transcriptScrollTo') {
|
|
196
|
+
scrollTranscriptTo(store, handlers, Number(event.offset ?? 0));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
185
199
|
if (event.kind !== 'key')
|
|
186
200
|
return;
|
|
187
201
|
const key = event;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thegitai/cli",
|
|
3
|
-
"version": "1.0.0-preview.
|
|
3
|
+
"version": "1.0.0-preview.15",
|
|
4
4
|
"description": "TheGitAI is an AI coding agent for your terminal. It indexes your repository, writes and edits files, runs commands, and builds features with you.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"@lydell/node-pty-linux-x64": "1.1.0",
|
|
38
38
|
"@lydell/node-pty-win32-arm64": "1.1.0",
|
|
39
39
|
"@lydell/node-pty-win32-x64": "1.1.0",
|
|
40
|
-
"@thegitai/tui-darwin-arm64": "1.0.0-preview.
|
|
41
|
-
"@thegitai/tui-darwin-x64": "1.0.0-preview.
|
|
42
|
-
"@thegitai/tui-linux-x64": "1.0.0-preview.
|
|
43
|
-
"@thegitai/tui-win32-x64": "1.0.0-preview.
|
|
40
|
+
"@thegitai/tui-darwin-arm64": "1.0.0-preview.15",
|
|
41
|
+
"@thegitai/tui-darwin-x64": "1.0.0-preview.15",
|
|
42
|
+
"@thegitai/tui-linux-x64": "1.0.0-preview.15",
|
|
43
|
+
"@thegitai/tui-win32-x64": "1.0.0-preview.15",
|
|
44
44
|
"@vscode/ripgrep": "1.18.0"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|