@kenkaiiii/ggcoder 4.3.225 → 4.3.226
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/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +18 -5
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/assistant-stream-flush-parity.test.d.ts +2 -0
- package/dist/ui/assistant-stream-flush-parity.test.d.ts.map +1 -0
- package/dist/ui/assistant-stream-flush-parity.test.js +85 -0
- package/dist/ui/assistant-stream-flush-parity.test.js.map +1 -0
- package/dist/ui/components/ChatLayout.d.ts +8 -1
- package/dist/ui/components/ChatLayout.d.ts.map +1 -1
- package/dist/ui/components/ChatLayout.js +4 -2
- package/dist/ui/components/ChatLayout.js.map +1 -1
- package/dist/ui/components/ChatLivePane.d.ts.map +1 -1
- package/dist/ui/components/ChatLivePane.js +15 -1
- package/dist/ui/components/ChatLivePane.js.map +1 -1
- package/dist/ui/components/InputArea.d.ts.map +1 -1
- package/dist/ui/components/InputArea.js +1 -3
- package/dist/ui/components/InputArea.js.map +1 -1
- package/dist/ui/components/SelectList.d.ts.map +1 -1
- package/dist/ui/components/SelectList.js +5 -0
- package/dist/ui/components/SelectList.js.map +1 -1
- package/dist/ui/components/SlashStyledSelectList.d.ts.map +1 -1
- package/dist/ui/components/SlashStyledSelectList.js +5 -0
- package/dist/ui/components/SlashStyledSelectList.js.map +1 -1
- package/dist/ui/components/ToolGroupExecution.d.ts +5 -2
- package/dist/ui/components/ToolGroupExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolGroupExecution.js +3 -3
- package/dist/ui/components/ToolGroupExecution.js.map +1 -1
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.d.ts.map +1 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.js +4 -1
- package/dist/ui/hooks/useChatLayoutMeasurements.js.map +1 -1
- package/dist/ui/live-area-clamp.test.d.ts +2 -0
- package/dist/ui/live-area-clamp.test.d.ts.map +1 -0
- package/dist/ui/live-area-clamp.test.js +79 -0
- package/dist/ui/live-area-clamp.test.js.map +1 -0
- package/dist/ui/live-area-height.d.ts +35 -0
- package/dist/ui/live-area-height.d.ts.map +1 -0
- package/dist/ui/live-area-height.js +75 -0
- package/dist/ui/live-area-height.js.map +1 -0
- package/dist/ui/live-area-height.test.d.ts +2 -0
- package/dist/ui/live-area-height.test.d.ts.map +1 -0
- package/dist/ui/live-area-height.test.js +67 -0
- package/dist/ui/live-area-height.test.js.map +1 -0
- package/dist/ui/live-frame-height.test.d.ts +2 -0
- package/dist/ui/live-frame-height.test.d.ts.map +1 -0
- package/dist/ui/live-frame-height.test.js +91 -0
- package/dist/ui/live-frame-height.test.js.map +1 -0
- package/dist/ui/terminal-history.d.ts.map +1 -1
- package/dist/ui/terminal-history.js +13 -4
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/terminal-history.test.js +9 -9
- package/dist/ui/terminal-history.test.js.map +1 -1
- package/dist/ui/tool-group-summary.d.ts +9 -1
- package/dist/ui/tool-group-summary.d.ts.map +1 -1
- package/dist/ui/tool-group-summary.js +7 -6
- package/dist/ui/tool-group-summary.js.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.d.ts.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.js +10 -2
- package/dist/ui/transcript/TranscriptRenderer.js.map +1 -1
- package/dist/ui/transcript/spacing.d.ts +15 -5
- package/dist/ui/transcript/spacing.d.ts.map +1 -1
- package/dist/ui/transcript/spacing.js +35 -18
- package/dist/ui/transcript/spacing.js.map +1 -1
- package/dist/ui/utils/assistant-stream-split.d.ts +17 -0
- package/dist/ui/utils/assistant-stream-split.d.ts.map +1 -1
- package/dist/ui/utils/assistant-stream-split.js +38 -1
- package/dist/ui/utils/assistant-stream-split.js.map +1 -1
- package/dist/ui/utils/assistant-stream-split.test.js +29 -6
- package/dist/ui/utils/assistant-stream-split.test.js.map +1 -1
- package/dist/ui/utils/terminal-input.d.ts +3 -0
- package/dist/ui/utils/terminal-input.d.ts.map +1 -0
- package/dist/ui/utils/terminal-input.js +28 -0
- package/dist/ui/utils/terminal-input.js.map +1 -0
- package/dist/ui/utils/terminal-input.test.d.ts +2 -0
- package/dist/ui/utils/terminal-input.test.d.ts.map +1 -0
- package/dist/ui/utils/terminal-input.test.js +15 -0
- package/dist/ui/utils/terminal-input.test.js.map +1 -0
- package/package.json +12 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAgC,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAyB,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAgC,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAyB,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatLayoutMeasurements.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/useChatLayoutMeasurements.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,wBAAwB,CAAC;AAEhC,UAAU,gCAAgC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,sBAAsB;IAC9B,kBAAkB,EAAE,0BAA0B,CAAC;IAC/C,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,yBAAyB,CAAC,EACxC,IAAI,EACJ,OAAO,EACP,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,SAAS,EACT,aAAa,EACb,QAAQ,EACR,WAAW,EACX,eAAe,EACf,oBAAoB,GACrB,EAAE,gCAAgC,GAAG,sBAAsB,
|
|
1
|
+
{"version":3,"file":"useChatLayoutMeasurements.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/useChatLayoutMeasurements.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,wBAAwB,CAAC;AAEhC,UAAU,gCAAgC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,UAAU,sBAAsB;IAC9B,kBAAkB,EAAE,0BAA0B,CAAC;IAC/C,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,yBAAyB,CAAC,EACxC,IAAI,EACJ,OAAO,EACP,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,SAAS,EACT,aAAa,EACb,QAAQ,EACR,WAAW,EACX,eAAe,EACf,oBAAoB,GACrB,EAAE,gCAAgC,GAAG,sBAAsB,CAqE3D"}
|
|
@@ -57,7 +57,10 @@ export function useChatLayoutMeasurements({ rows, columns, backgroundTaskCount,
|
|
|
57
57
|
footerFitsOnOneLine,
|
|
58
58
|
});
|
|
59
59
|
const stableControlsRows = controlsHeight > 0 ? controlsHeight : chatControlsLayout.controlsRows;
|
|
60
|
-
|
|
60
|
+
// Subtract a 2-row cushion (not 1) so the total live frame stays <= rows - 1
|
|
61
|
+
// even with rounding from the ResizeObserver-measured controlsHeight, keeping
|
|
62
|
+
// Ink out of its fullscreen clearTerminal path that snaps the controls upward.
|
|
63
|
+
const measuredLiveAreaRows = Math.max(MIN_LIVE_AREA_ROWS, rows - stableControlsRows - 2);
|
|
61
64
|
return {
|
|
62
65
|
footerStatusLayout,
|
|
63
66
|
activityVisible,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatLayoutMeasurements.js","sourceRoot":"","sources":["../../../src/ui/hooks/useChatLayoutMeasurements.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useChatLayoutMeasurements.js","sourceRoot":"","sources":["../../../src/ui/hooks/useChatLayoutMeasurements.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-area-clamp.test.d.ts","sourceRoot":"","sources":["../../src/ui/live-area-clamp.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Text, render } from "ink";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { ChatLivePane } from "./components/ChatLivePane.js";
|
|
6
|
+
import { ChatLayout, ChatControls } from "./components/ChatLayout.js";
|
|
7
|
+
import { TerminalSizeProvider } from "./hooks/useTerminalSize.js";
|
|
8
|
+
import { useTheme } from "./theme/theme.js";
|
|
9
|
+
import { renderTranscriptItem } from "./transcript/TranscriptRenderer.js";
|
|
10
|
+
const ROWS = 24;
|
|
11
|
+
const COLUMNS = 80;
|
|
12
|
+
const CONTROLS_ROWS = 4;
|
|
13
|
+
// Mirror useChatLayoutMeasurements: rows - controlsRows - 2 (widened cushion).
|
|
14
|
+
const measuredLiveAreaRows = Math.max(3, ROWS - CONTROLS_ROWS - 2);
|
|
15
|
+
function stripAnsi(v) {
|
|
16
|
+
return v.replace(new RegExp(String.raw `\u001B\[[0-?]*[ -/]*[@-~]`, "g"), "");
|
|
17
|
+
}
|
|
18
|
+
function Harness({ liveItems, streamingText, }) {
|
|
19
|
+
const theme = useTheme();
|
|
20
|
+
const renderItem = (item, index, items) => renderTranscriptItem({
|
|
21
|
+
item,
|
|
22
|
+
index,
|
|
23
|
+
items,
|
|
24
|
+
version: "0",
|
|
25
|
+
currentModel: "m",
|
|
26
|
+
currentProvider: "anthropic",
|
|
27
|
+
displayedCwd: "/tmp",
|
|
28
|
+
columns: COLUMNS,
|
|
29
|
+
theme,
|
|
30
|
+
renderMarkdown: true,
|
|
31
|
+
measuredLiveAreaRows,
|
|
32
|
+
});
|
|
33
|
+
return (_jsxs(ChatLayout, { columns: COLUMNS, children: [_jsx(ChatLivePane, { liveItems: liveItems, renderItem: renderItem, isRunning: true, visibleStreamingText: streamingText, streamingThinking: "", thinkingMs: 0, reserveStreamingSpacing: false, renderMarkdown: true, measuredLiveAreaRows: measuredLiveAreaRows, assistantMarginTop: 0, streamingContinuation: false }), _jsx(ChatControls, { controlsRef: () => { }, children: Array.from({ length: CONTROLS_ROWS }, (_, i) => (_jsxs(Text, { children: ["CONTROL_", i] }, i))) })] }));
|
|
34
|
+
}
|
|
35
|
+
function frameHeight(node) {
|
|
36
|
+
let output = "";
|
|
37
|
+
const stdout = {
|
|
38
|
+
columns: COLUMNS,
|
|
39
|
+
rows: ROWS,
|
|
40
|
+
write(chunk) {
|
|
41
|
+
output += chunk;
|
|
42
|
+
return true;
|
|
43
|
+
},
|
|
44
|
+
on() { },
|
|
45
|
+
off() { },
|
|
46
|
+
};
|
|
47
|
+
const { unmount } = render(_jsx(TerminalSizeProvider, { children: node }), {
|
|
48
|
+
stdout,
|
|
49
|
+
columns: COLUMNS,
|
|
50
|
+
rows: ROWS,
|
|
51
|
+
debug: true,
|
|
52
|
+
});
|
|
53
|
+
const height = stripAnsi(output).split("\n").length;
|
|
54
|
+
unmount();
|
|
55
|
+
return height;
|
|
56
|
+
}
|
|
57
|
+
const longText = Array.from({ length: 60 }, (_, i) => `response line ${i + 1}`).join("\n");
|
|
58
|
+
describe("live area clamp", () => {
|
|
59
|
+
it("keeps multiple accumulated assistant blocks below the terminal height", () => {
|
|
60
|
+
// The "jump on final response": Ink redraws from the top once a frame's
|
|
61
|
+
// height reaches the terminal rows. Stacked finalized assistant turns must
|
|
62
|
+
// stay strictly below rows so that never triggers.
|
|
63
|
+
const height = frameHeight(_jsx(Harness, { liveItems: [
|
|
64
|
+
{ kind: "assistant", id: "a1", text: longText },
|
|
65
|
+
{ kind: "assistant", id: "a2", text: longText },
|
|
66
|
+
], streamingText: "" }));
|
|
67
|
+
expect(height).toBeLessThan(ROWS);
|
|
68
|
+
});
|
|
69
|
+
it("keeps a finalized block plus in-flight streaming below the terminal height", () => {
|
|
70
|
+
const height = frameHeight(_jsx(Harness, { liveItems: [{ kind: "assistant", id: "a1", text: longText }], streamingText: longText }));
|
|
71
|
+
expect(height).toBeLessThan(ROWS);
|
|
72
|
+
});
|
|
73
|
+
it("stays compact (no reserved blank rows) when live content is short", () => {
|
|
74
|
+
const height = frameHeight(_jsx(Harness, { liveItems: [{ kind: "assistant", id: "a1", text: "short reply" }], streamingText: "" }));
|
|
75
|
+
// 1 assistant row + 4 control rows, no padding up to the budget.
|
|
76
|
+
expect(height).toBeLessThanOrEqual(CONTROLS_ROWS + 2);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=live-area-clamp.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-area-clamp.test.js","sourceRoot":"","sources":["../../src/ui/live-area-clamp.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CompletedItem } from "./app-items.js";
|
|
2
|
+
/**
|
|
3
|
+
* Cheap, deterministic estimate of how many terminal rows a block of text
|
|
4
|
+
* occupies once wrapped to `width`. Biased high (uses display width and counts
|
|
5
|
+
* at least one row per source line) so the live-area clamp never UNDER-counts
|
|
6
|
+
* and lets the frame overflow past the terminal height.
|
|
7
|
+
*/
|
|
8
|
+
export declare function estimateWrappedRows(text: string, columns: number): number;
|
|
9
|
+
/**
|
|
10
|
+
* Estimate the total rendered height (in terminal rows) of the live area:
|
|
11
|
+
* every live item plus the in-flight streaming block. Each text block is
|
|
12
|
+
* individually capped at `perItemBudget` because AssistantMessage/Markdown
|
|
13
|
+
* truncate to that height, but their SUM is what can overflow the terminal —
|
|
14
|
+
* which is exactly what this measures.
|
|
15
|
+
*/
|
|
16
|
+
export declare function estimateLiveAreaRows({ liveItems, streamingText, columns, perItemBudget, }: {
|
|
17
|
+
liveItems: readonly CompletedItem[];
|
|
18
|
+
streamingText: string;
|
|
19
|
+
columns: number;
|
|
20
|
+
perItemBudget: number;
|
|
21
|
+
}): number;
|
|
22
|
+
/**
|
|
23
|
+
* Decide whether the live area must be hard-clamped to `liveAreaBudget` rows.
|
|
24
|
+
* Returns the clamp height when the estimated content would overflow the
|
|
25
|
+
* budget (so the bottom-anchored container clips the oldest rows and keeps the
|
|
26
|
+
* Ink-rendered frame strictly below the terminal height), or `undefined` when
|
|
27
|
+
* the content fits and the area should stay compact (no reserved blank rows).
|
|
28
|
+
*/
|
|
29
|
+
export declare function getLiveAreaClampRows({ liveItems, streamingText, columns, liveAreaBudget, }: {
|
|
30
|
+
liveItems: readonly CompletedItem[];
|
|
31
|
+
streamingText: string;
|
|
32
|
+
columns: number;
|
|
33
|
+
liveAreaBudget: number;
|
|
34
|
+
}): number | undefined;
|
|
35
|
+
//# sourceMappingURL=live-area-height.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-area-height.d.ts","sourceRoot":"","sources":["../../src/ui/live-area-height.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAWpD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKzE;AAWD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,aAAa,EACb,OAAO,EACP,aAAa,GACd,EAAE;IACD,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAmBT;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,aAAa,EACb,OAAO,EACP,cAAc,GACf,EAAE;IACD,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB,GAAG,MAAM,GAAG,SAAS,CAQrB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import stringWidth from "string-width";
|
|
2
|
+
/**
|
|
3
|
+
* Width the assistant/streaming markdown body wraps to, mirroring
|
|
4
|
+
* AssistantMessage's content box: columns - RESPONSE_LEFT_PADDING(1) -
|
|
5
|
+
* PREFIX_WIDTH(2) - RESPONSE_RIGHT_GUARD(1).
|
|
6
|
+
*/
|
|
7
|
+
function bodyWidth(columns) {
|
|
8
|
+
return Math.max(10, columns - 4);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Cheap, deterministic estimate of how many terminal rows a block of text
|
|
12
|
+
* occupies once wrapped to `width`. Biased high (uses display width and counts
|
|
13
|
+
* at least one row per source line) so the live-area clamp never UNDER-counts
|
|
14
|
+
* and lets the frame overflow past the terminal height.
|
|
15
|
+
*/
|
|
16
|
+
export function estimateWrappedRows(text, columns) {
|
|
17
|
+
const width = bodyWidth(columns);
|
|
18
|
+
return text
|
|
19
|
+
.split("\n")
|
|
20
|
+
.reduce((rows, line) => rows + Math.max(1, Math.ceil(stringWidth(line) / width)), 0);
|
|
21
|
+
}
|
|
22
|
+
const THINKING_HEADER_ROWS = 2;
|
|
23
|
+
// Per-block decoration not captured by the wrapped body: the top-spacing margin
|
|
24
|
+
// plus the response prefix line allowance.
|
|
25
|
+
const BLOCK_OVERHEAD_ROWS = 1;
|
|
26
|
+
// Conservative allowance for non-text live rows (tool headers, step markers,
|
|
27
|
+
// info/error lines). These are normally flushed to scrollback quickly, but
|
|
28
|
+
// estimate generously while they linger so the clamp engages early.
|
|
29
|
+
const NON_TEXT_ROW_ESTIMATE = 3;
|
|
30
|
+
/**
|
|
31
|
+
* Estimate the total rendered height (in terminal rows) of the live area:
|
|
32
|
+
* every live item plus the in-flight streaming block. Each text block is
|
|
33
|
+
* individually capped at `perItemBudget` because AssistantMessage/Markdown
|
|
34
|
+
* truncate to that height, but their SUM is what can overflow the terminal —
|
|
35
|
+
* which is exactly what this measures.
|
|
36
|
+
*/
|
|
37
|
+
export function estimateLiveAreaRows({ liveItems, streamingText, columns, perItemBudget, }) {
|
|
38
|
+
let rows = 0;
|
|
39
|
+
for (const item of liveItems) {
|
|
40
|
+
if (item.kind === "assistant") {
|
|
41
|
+
const textRows = item.text.trim().length > 0 ? estimateWrappedRows(item.text, columns) : 0;
|
|
42
|
+
const thinkingRows = item.thinking ? THINKING_HEADER_ROWS : 0;
|
|
43
|
+
rows += Math.min(textRows, perItemBudget) + thinkingRows + BLOCK_OVERHEAD_ROWS;
|
|
44
|
+
}
|
|
45
|
+
else if (item.kind === "tombstone" || item.kind === "banner") {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
rows += NON_TEXT_ROW_ESTIMATE;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const trimmedStreaming = streamingText.trim();
|
|
53
|
+
if (trimmedStreaming.length > 0) {
|
|
54
|
+
rows +=
|
|
55
|
+
Math.min(estimateWrappedRows(streamingText, columns), perItemBudget) + BLOCK_OVERHEAD_ROWS;
|
|
56
|
+
}
|
|
57
|
+
return rows;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Decide whether the live area must be hard-clamped to `liveAreaBudget` rows.
|
|
61
|
+
* Returns the clamp height when the estimated content would overflow the
|
|
62
|
+
* budget (so the bottom-anchored container clips the oldest rows and keeps the
|
|
63
|
+
* Ink-rendered frame strictly below the terminal height), or `undefined` when
|
|
64
|
+
* the content fits and the area should stay compact (no reserved blank rows).
|
|
65
|
+
*/
|
|
66
|
+
export function getLiveAreaClampRows({ liveItems, streamingText, columns, liveAreaBudget, }) {
|
|
67
|
+
const estimated = estimateLiveAreaRows({
|
|
68
|
+
liveItems,
|
|
69
|
+
streamingText,
|
|
70
|
+
columns,
|
|
71
|
+
perItemBudget: liveAreaBudget,
|
|
72
|
+
});
|
|
73
|
+
return estimated > liveAreaBudget ? liveAreaBudget : undefined;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=live-area-height.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-area-height.js","sourceRoot":"","sources":["../../src/ui/live-area-height.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,cAAc,CAAC;AAGvC;;;;GAIG;AACH,SAAS,SAAS,CAAC,OAAe;IAChC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,OAAe;IAC/D,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,gFAAgF;AAChF,2CAA2C;AAC3C,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,6EAA6E;AAC7E,2EAA2E;AAC3E,oEAAoE;AACpE,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,SAAS,EACT,aAAa,EACb,OAAO,EACP,aAAa,GAMd;IACC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3F,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9D,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,GAAG,YAAY,GAAG,mBAAmB,CAAC;QACjF,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC/D,SAAS;QACX,CAAC;aAAM,CAAC;YACN,IAAI,IAAI,qBAAqB,CAAC;QAChC,CAAC;IACH,CAAC;IACD,MAAM,gBAAgB,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC;IAC9C,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,IAAI;YACF,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE,aAAa,CAAC,GAAG,mBAAmB,CAAC;IAC/F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,SAAS,EACT,aAAa,EACb,OAAO,EACP,cAAc,GAMf;IACC,MAAM,SAAS,GAAG,oBAAoB,CAAC;QACrC,SAAS;QACT,aAAa;QACb,OAAO;QACP,aAAa,EAAE,cAAc;KAC9B,CAAC,CAAC;IACH,OAAO,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-area-height.test.d.ts","sourceRoot":"","sources":["../../src/ui/live-area-height.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { estimateWrappedRows, estimateLiveAreaRows, getLiveAreaClampRows, } from "./live-area-height.js";
|
|
3
|
+
const COLUMNS = 80;
|
|
4
|
+
function assistant(id, lines) {
|
|
5
|
+
return {
|
|
6
|
+
kind: "assistant",
|
|
7
|
+
id,
|
|
8
|
+
text: Array.from({ length: lines }, (_, i) => `line ${i + 1}`).join("\n"),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
describe("estimateWrappedRows", () => {
|
|
12
|
+
it("counts one row per short source line", () => {
|
|
13
|
+
expect(estimateWrappedRows("a\nb\nc", COLUMNS)).toBe(3);
|
|
14
|
+
});
|
|
15
|
+
it("counts wrapped rows for lines wider than the body width", () => {
|
|
16
|
+
// body width = columns - 4 = 76; a 200-char line wraps to ceil(200/76) = 3.
|
|
17
|
+
expect(estimateWrappedRows("x".repeat(200), COLUMNS)).toBe(3);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe("estimateLiveAreaRows", () => {
|
|
21
|
+
it("sums per-block heights, capping each block at the per-item budget", () => {
|
|
22
|
+
const rows = estimateLiveAreaRows({
|
|
23
|
+
liveItems: [assistant("a1", 40), assistant("a2", 40)],
|
|
24
|
+
streamingText: "",
|
|
25
|
+
columns: COLUMNS,
|
|
26
|
+
perItemBudget: 18,
|
|
27
|
+
});
|
|
28
|
+
// Each block capped at 18 + 1 overhead => 2 * 19 = 38.
|
|
29
|
+
expect(rows).toBe(38);
|
|
30
|
+
});
|
|
31
|
+
it("includes the in-flight streaming block", () => {
|
|
32
|
+
const rows = estimateLiveAreaRows({
|
|
33
|
+
liveItems: [],
|
|
34
|
+
streamingText: Array.from({ length: 40 }, (_, i) => `s ${i}`).join("\n"),
|
|
35
|
+
columns: COLUMNS,
|
|
36
|
+
perItemBudget: 18,
|
|
37
|
+
});
|
|
38
|
+
expect(rows).toBe(19);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("getLiveAreaClampRows", () => {
|
|
42
|
+
it("clamps to the budget when stacked blocks would overflow it", () => {
|
|
43
|
+
expect(getLiveAreaClampRows({
|
|
44
|
+
liveItems: [assistant("a1", 40), assistant("a2", 40)],
|
|
45
|
+
streamingText: "",
|
|
46
|
+
columns: COLUMNS,
|
|
47
|
+
liveAreaBudget: 18,
|
|
48
|
+
})).toBe(18);
|
|
49
|
+
});
|
|
50
|
+
it("stays compact (no clamp) when content fits the budget", () => {
|
|
51
|
+
expect(getLiveAreaClampRows({
|
|
52
|
+
liveItems: [assistant("a1", 3)],
|
|
53
|
+
streamingText: "",
|
|
54
|
+
columns: COLUMNS,
|
|
55
|
+
liveAreaBudget: 18,
|
|
56
|
+
})).toBeUndefined();
|
|
57
|
+
});
|
|
58
|
+
it("stays compact when the live area is empty", () => {
|
|
59
|
+
expect(getLiveAreaClampRows({
|
|
60
|
+
liveItems: [],
|
|
61
|
+
streamingText: "",
|
|
62
|
+
columns: COLUMNS,
|
|
63
|
+
liveAreaBudget: 18,
|
|
64
|
+
})).toBeUndefined();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=live-area-height.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-area-height.test.js","sourceRoot":"","sources":["../../src/ui/live-area-height.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-frame-height.test.d.ts","sourceRoot":"","sources":["../../src/ui/live-frame-height.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { renderToString } from "ink";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { renderTranscriptItem } from "./transcript/TranscriptRenderer.js";
|
|
6
|
+
import { getChatControlsLayoutDecision, MIN_LIVE_AREA_ROWS } from "./layout-decisions.js";
|
|
7
|
+
import { TerminalSizeProvider } from "./hooks/useTerminalSize.js";
|
|
8
|
+
import { useTheme } from "./theme/theme.js";
|
|
9
|
+
function stripAnsi(value) {
|
|
10
|
+
return value.replace(new RegExp(String.raw `\u001B\[[0-?]*[ -/]*[@-~]`, "g"), "");
|
|
11
|
+
}
|
|
12
|
+
const noFooterStatus = {
|
|
13
|
+
hasBackgroundTasks: false,
|
|
14
|
+
hasUpdateNotice: false,
|
|
15
|
+
stack: false,
|
|
16
|
+
compactBackgroundTasks: false,
|
|
17
|
+
};
|
|
18
|
+
const ROWS = 24;
|
|
19
|
+
const COLUMNS = 60;
|
|
20
|
+
// Worst case for the live-frame jump: the agent has just gone idle, so the
|
|
21
|
+
// activity/status row disappears and the controls shrink — which grows the live
|
|
22
|
+
// area to nearly fill the screen right as the finalized assistant row renders.
|
|
23
|
+
const idleControlsRows = getChatControlsLayoutDecision({
|
|
24
|
+
rows: ROWS,
|
|
25
|
+
columns: COLUMNS,
|
|
26
|
+
agentRunning: false,
|
|
27
|
+
activityVisible: false,
|
|
28
|
+
doneStatusVisible: false,
|
|
29
|
+
stallStatusVisible: false,
|
|
30
|
+
exitPending: false,
|
|
31
|
+
footerStatusLayout: noFooterStatus,
|
|
32
|
+
taskBarExpanded: false,
|
|
33
|
+
goalStatusEntryCount: 0,
|
|
34
|
+
footerFitsOnOneLine: true,
|
|
35
|
+
}).controlsRows;
|
|
36
|
+
// Mirror useChatLayoutMeasurements: rows - controlsRows - 2 (the widened cushion).
|
|
37
|
+
const measuredLiveAreaRows = Math.max(MIN_LIVE_AREA_ROWS, ROWS - idleControlsRows - 2);
|
|
38
|
+
// A previous tool boundary forces the assistant transcript item's top margin.
|
|
39
|
+
const previousToolGroup = {
|
|
40
|
+
kind: "tool_group",
|
|
41
|
+
id: "tool-group-1",
|
|
42
|
+
tools: [],
|
|
43
|
+
};
|
|
44
|
+
function ThemedTranscriptItem({ item }) {
|
|
45
|
+
const theme = useTheme();
|
|
46
|
+
const items = [previousToolGroup, item];
|
|
47
|
+
return (_jsx(_Fragment, { children: renderTranscriptItem({
|
|
48
|
+
item,
|
|
49
|
+
index: 1,
|
|
50
|
+
items,
|
|
51
|
+
version: "0.0.0-test",
|
|
52
|
+
currentModel: "test-model",
|
|
53
|
+
currentProvider: "anthropic",
|
|
54
|
+
displayedCwd: "/tmp",
|
|
55
|
+
columns: COLUMNS,
|
|
56
|
+
theme,
|
|
57
|
+
renderMarkdown: true,
|
|
58
|
+
measuredLiveAreaRows,
|
|
59
|
+
}) }));
|
|
60
|
+
}
|
|
61
|
+
function renderFrameLineCount(item) {
|
|
62
|
+
const output = renderToString(_jsx(TerminalSizeProvider, { children: _jsx(ThemedTranscriptItem, { item: item }) }), { columns: COLUMNS });
|
|
63
|
+
return stripAnsi(output).split("\n").filter(Boolean).length;
|
|
64
|
+
}
|
|
65
|
+
describe("live frame height", () => {
|
|
66
|
+
it("keeps a tall finalized assistant frame (with thinking) below terminal height", () => {
|
|
67
|
+
const text = Array.from({ length: ROWS * 3 }, (_, index) => `final line ${index + 1}`).join("\n");
|
|
68
|
+
const item = {
|
|
69
|
+
kind: "assistant",
|
|
70
|
+
id: "assistant-tall-thinking",
|
|
71
|
+
text,
|
|
72
|
+
thinking: "internal reasoning that collapses to a header",
|
|
73
|
+
thinkingMs: 1200,
|
|
74
|
+
};
|
|
75
|
+
const lines = renderFrameLineCount(item);
|
|
76
|
+
// Adding back the controls must never reach the terminal height, or Ink
|
|
77
|
+
// enters its fullscreen clearTerminal path and snaps the controls to the top.
|
|
78
|
+
expect(lines + idleControlsRows).toBeLessThanOrEqual(ROWS - 1);
|
|
79
|
+
});
|
|
80
|
+
it("keeps a tall finalized assistant frame (no thinking) below terminal height", () => {
|
|
81
|
+
const text = Array.from({ length: ROWS * 3 }, (_, index) => `final line ${index + 1}`).join("\n");
|
|
82
|
+
const item = {
|
|
83
|
+
kind: "assistant",
|
|
84
|
+
id: "assistant-tall-plain",
|
|
85
|
+
text,
|
|
86
|
+
};
|
|
87
|
+
const lines = renderFrameLineCount(item);
|
|
88
|
+
expect(lines + idleControlsRows).toBeLessThanOrEqual(ROWS - 1);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
//# sourceMappingURL=live-frame-height.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-frame-height.test.js","sourceRoot":"","sources":["../../src/ui/live-frame-height.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-history.d.ts","sourceRoot":"","sources":["../../src/ui/terminal-history.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAuF9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,CACH,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,GAC5D,IAAI,CAAC;IACR,KAAK,IAAI,IAAI,CAAC;IACd,YAAY,IAAI,IAAI,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,MAAuB,GACxB,GAAE,6BAAkC,GAAG,sBAAsB,
|
|
1
|
+
{"version":3,"file":"terminal-history.d.ts","sourceRoot":"","sources":["../../src/ui/terminal-history.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAuF9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,CACH,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,GAC5D,IAAI,CAAC;IACR,KAAK,IAAI,IAAI,CAAC;IACd,YAAY,IAAI,IAAI,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,MAAuB,GACxB,GAAE,6BAAkC,GAAG,sBAAsB,CAkD7D;AAED,wBAAgB,uCAAuC,CACrD,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CA+IR"}
|
|
@@ -59,13 +59,22 @@ export function createTerminalHistoryPrinter({ stream = process.stdout, } = {})
|
|
|
59
59
|
continue;
|
|
60
60
|
const output = serializeCompletedItemToTerminalHistory(item, context);
|
|
61
61
|
const endsWithBlankLine = item.kind === "banner";
|
|
62
|
+
// A continuation assistant chunk is the next paragraph of a response
|
|
63
|
+
// whose earlier paragraphs were already flushed mid-stream. Re-insert
|
|
64
|
+
// the blank line that separated them so the reassembled scrollback
|
|
65
|
+
// matches the whole response (assistant→assistant is otherwise compact).
|
|
66
|
+
const isContinuationParagraph = item.kind === "assistant" &&
|
|
67
|
+
item.continuation === true &&
|
|
68
|
+
previousPrintedKind === "assistant";
|
|
62
69
|
const formatted = formatHistoryWrite(output, {
|
|
63
70
|
leadingSeparator: item.kind === "plan_transition"
|
|
64
71
|
? false
|
|
65
|
-
:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
: isContinuationParagraph
|
|
73
|
+
? true
|
|
74
|
+
: shouldSeparateTranscriptItems({
|
|
75
|
+
previousKind: previousPrintedKind ?? undefined,
|
|
76
|
+
currentKind: item.kind,
|
|
77
|
+
}),
|
|
69
78
|
trailingBlankLine: endsWithBlankLine,
|
|
70
79
|
trailingNewlines: item.kind === "user" ? 1 : undefined,
|
|
71
80
|
});
|