@prestyj/cli 4.6.4 → 4.10.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/dist/cli/auth.d.ts.map +1 -1
- package/dist/cli/auth.js +11 -10
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/mcp.js +1 -1
- package/dist/cli/shared.d.ts +12 -0
- package/dist/cli/shared.d.ts.map +1 -1
- package/dist/cli/shared.js +31 -6
- package/dist/cli/shared.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +63 -62
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +7 -14
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -17
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-compaction.test.js +1 -1
- package/dist/core/agent-session-compaction.test.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +6 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -58
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -254
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/auto-update.d.ts +4 -26
- package/dist/core/auto-update.d.ts.map +1 -1
- package/dist/core/auto-update.js +12 -237
- package/dist/core/auto-update.js.map +1 -1
- package/dist/core/claude-code-version.d.ts +1 -9
- package/dist/core/claude-code-version.d.ts.map +1 -1
- package/dist/core/claude-code-version.js +2 -105
- package/dist/core/claude-code-version.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +2 -2
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/file-lock.d.ts +1 -5
- package/dist/core/file-lock.d.ts.map +1 -1
- package/dist/core/file-lock.js +2 -75
- package/dist/core/file-lock.js.map +1 -1
- package/dist/core/logger.d.ts +4 -17
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +21 -110
- package/dist/core/logger.js.map +1 -1
- package/dist/core/lsp/client.d.ts +63 -0
- package/dist/core/lsp/client.d.ts.map +1 -0
- package/dist/core/lsp/client.js +215 -0
- package/dist/core/lsp/client.js.map +1 -0
- package/dist/core/lsp/format.d.ts +12 -0
- package/dist/core/lsp/format.d.ts.map +1 -0
- package/dist/core/lsp/format.js +30 -0
- package/dist/core/lsp/format.js.map +1 -0
- package/dist/core/lsp/format.test.d.ts +2 -0
- package/dist/core/lsp/format.test.d.ts.map +1 -0
- package/dist/core/lsp/format.test.js +56 -0
- package/dist/core/lsp/format.test.js.map +1 -0
- package/dist/core/lsp/integration.test.d.ts +2 -0
- package/dist/core/lsp/integration.test.d.ts.map +1 -0
- package/dist/core/lsp/integration.test.js +60 -0
- package/dist/core/lsp/integration.test.js.map +1 -0
- package/dist/core/lsp/jsonrpc.d.ts +32 -0
- package/dist/core/lsp/jsonrpc.d.ts.map +1 -0
- package/dist/core/lsp/jsonrpc.js +141 -0
- package/dist/core/lsp/jsonrpc.js.map +1 -0
- package/dist/core/lsp/jsonrpc.test.d.ts +2 -0
- package/dist/core/lsp/jsonrpc.test.d.ts.map +1 -0
- package/dist/core/lsp/jsonrpc.test.js +127 -0
- package/dist/core/lsp/jsonrpc.test.js.map +1 -0
- package/dist/core/lsp/manager.d.ts +40 -0
- package/dist/core/lsp/manager.d.ts.map +1 -0
- package/dist/core/lsp/manager.js +135 -0
- package/dist/core/lsp/manager.js.map +1 -0
- package/dist/core/lsp/manager.test.d.ts +2 -0
- package/dist/core/lsp/manager.test.d.ts.map +1 -0
- package/dist/core/lsp/manager.test.js +119 -0
- package/dist/core/lsp/manager.test.js.map +1 -0
- package/dist/core/lsp/servers.d.ts +45 -0
- package/dist/core/lsp/servers.d.ts.map +1 -0
- package/dist/core/lsp/servers.js +247 -0
- package/dist/core/lsp/servers.js.map +1 -0
- package/dist/core/mcp/defaults.d.ts +1 -1
- package/dist/core/mcp/defaults.js +1 -1
- package/dist/core/mcp/store.d.ts +1 -1
- package/dist/core/mcp/store.test.js +1 -1
- package/dist/core/mcp/store.test.js.map +1 -1
- package/dist/core/model-registry.d.ts +1 -75
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +4 -344
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/oauth/anthropic.d.ts +1 -3
- package/dist/core/oauth/anthropic.d.ts.map +1 -1
- package/dist/core/oauth/anthropic.js +2 -96
- package/dist/core/oauth/anthropic.js.map +1 -1
- package/dist/core/oauth/gemini.d.ts +1 -3
- package/dist/core/oauth/gemini.d.ts.map +1 -1
- package/dist/core/oauth/gemini.js +2 -385
- package/dist/core/oauth/gemini.js.map +1 -1
- package/dist/core/oauth/kimi.d.ts +1 -45
- package/dist/core/oauth/kimi.d.ts.map +1 -1
- package/dist/core/oauth/kimi.js +2 -277
- package/dist/core/oauth/kimi.js.map +1 -1
- package/dist/core/oauth/openai.d.ts +1 -3
- package/dist/core/oauth/openai.d.ts.map +1 -1
- package/dist/core/oauth/openai.js +2 -187
- package/dist/core/oauth/openai.js.map +1 -1
- package/dist/core/oauth/pkce.d.ts +1 -4
- package/dist/core/oauth/pkce.d.ts.map +1 -1
- package/dist/core/oauth/pkce.js +2 -16
- package/dist/core/oauth/pkce.js.map +1 -1
- package/dist/core/oauth/types.d.ts +1 -13
- package/dist/core/oauth/types.d.ts.map +1 -1
- package/dist/core/process-manager.d.ts +10 -0
- package/dist/core/process-manager.d.ts.map +1 -1
- package/dist/core/process-manager.js +45 -1
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/prompt-commands.d.ts.map +1 -1
- package/dist/core/prompt-commands.js +20 -7
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/session-manager.d.ts +26 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +99 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-manager.test.d.ts +2 -0
- package/dist/core/session-manager.test.d.ts.map +1 -0
- package/dist/core/session-manager.test.js +113 -0
- package/dist/core/session-manager.test.js.map +1 -0
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +6 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/telegram.d.ts +1 -112
- package/dist/core/telegram.d.ts.map +1 -1
- package/dist/core/telegram.js +2 -251
- package/dist/core/telegram.js.map +1 -1
- package/dist/core/thinking-level.d.ts +1 -4
- package/dist/core/thinking-level.d.ts.map +1 -1
- package/dist/core/thinking-level.js +3 -58
- package/dist/core/thinking-level.js.map +1 -1
- package/dist/core/voice-transcriber.d.ts +1 -32
- package/dist/core/voice-transcriber.d.ts.map +1 -1
- package/dist/core/voice-transcriber.js +3 -112
- package/dist/core/voice-transcriber.js.map +1 -1
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +5 -2
- package/dist/interactive.js.map +1 -1
- package/dist/modes/agent-home-mode.d.ts.map +1 -1
- package/dist/modes/agent-home-mode.js +10 -38
- package/dist/modes/agent-home-mode.js.map +1 -1
- package/dist/modes/serve-mode.d.ts.map +1 -1
- package/dist/modes/serve-mode.js +11 -39
- package/dist/modes/serve-mode.js.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +13 -6
- package/dist/session.js.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +6 -3
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts +3 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +15 -3
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/edit.test.js +70 -0
- package/dist/tools/edit.test.js.map +1 -1
- package/dist/tools/goals.d.ts +1 -1
- package/dist/tools/index.d.ts +15 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +16 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/task-send.d.ts +12 -0
- package/dist/tools/task-send.d.ts.map +1 -0
- package/dist/tools/task-send.js +34 -0
- package/dist/tools/task-send.js.map +1 -0
- package/dist/tools/task-send.test.d.ts +2 -0
- package/dist/tools/task-send.test.d.ts.map +1 -0
- package/dist/tools/task-send.test.js +95 -0
- package/dist/tools/task-send.test.js.map +1 -0
- package/dist/tools/write.d.ts +3 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +13 -2
- package/dist/tools/write.js.map +1 -1
- package/dist/tools/write.test.js +33 -0
- package/dist/tools/write.test.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/App.d.ts +16 -0
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +126 -12
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/anchor-pad-reclaim.test.d.ts +2 -0
- package/dist/ui/anchor-pad-reclaim.test.d.ts.map +1 -0
- package/dist/ui/anchor-pad-reclaim.test.js +146 -0
- package/dist/ui/anchor-pad-reclaim.test.js.map +1 -0
- package/dist/ui/app-items.d.ts +14 -0
- package/dist/ui/app-items.d.ts.map +1 -1
- package/dist/ui/app-items.js +13 -0
- package/dist/ui/app-items.js.map +1 -1
- package/dist/ui/app-items.test.js +17 -1
- package/dist/ui/app-items.test.js.map +1 -1
- package/dist/ui/atomic-flush-regression.test.d.ts +2 -0
- package/dist/ui/atomic-flush-regression.test.d.ts.map +1 -0
- package/dist/ui/atomic-flush-regression.test.js +218 -0
- package/dist/ui/atomic-flush-regression.test.js.map +1 -0
- package/dist/ui/components/AssistantMessage.test.js +32 -1
- package/dist/ui/components/AssistantMessage.test.js.map +1 -1
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js +1 -0
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/InputArea.test.js +11 -5
- package/dist/ui/components/InputArea.test.js.map +1 -1
- package/dist/ui/components/Markdown.d.ts.map +1 -1
- package/dist/ui/components/Markdown.js +9 -1
- package/dist/ui/components/Markdown.js.map +1 -1
- package/dist/ui/footer-jump-regression.test.js +56 -9
- package/dist/ui/footer-jump-regression.test.js.map +1 -1
- package/dist/ui/frame-clip-regression.test.d.ts +2 -0
- package/dist/ui/frame-clip-regression.test.d.ts.map +1 -0
- package/dist/ui/frame-clip-regression.test.js +215 -0
- package/dist/ui/frame-clip-regression.test.js.map +1 -0
- package/dist/ui/hooks/useTranscriptHistory.d.ts +9 -1
- package/dist/ui/hooks/useTranscriptHistory.d.ts.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.js +51 -19
- package/dist/ui/hooks/useTranscriptHistory.js.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.sessionstore.test.d.ts +2 -0
- package/dist/ui/hooks/useTranscriptHistory.sessionstore.test.d.ts.map +1 -0
- package/dist/ui/hooks/useTranscriptHistory.sessionstore.test.js +81 -0
- package/dist/ui/hooks/useTranscriptHistory.sessionstore.test.js.map +1 -0
- package/dist/ui/live-area-clamp.test.js +37 -0
- package/dist/ui/live-area-clamp.test.js.map +1 -1
- package/dist/ui/live-area-height.d.ts.map +1 -1
- package/dist/ui/live-area-height.js +13 -6
- package/dist/ui/live-area-height.js.map +1 -1
- package/dist/ui/live-area-height.test.js +9 -0
- package/dist/ui/live-area-height.test.js.map +1 -1
- package/dist/ui/live-item-flush.d.ts +28 -0
- package/dist/ui/live-item-flush.d.ts.map +1 -1
- package/dist/ui/live-item-flush.js +44 -0
- package/dist/ui/live-item-flush.js.map +1 -1
- package/dist/ui/live-item-flush.test.js +83 -1
- package/dist/ui/live-item-flush.test.js.map +1 -1
- package/dist/ui/login.d.ts.map +1 -1
- package/dist/ui/login.js +12 -30
- package/dist/ui/login.js.map +1 -1
- package/dist/ui/mcp.d.ts +1 -2
- package/dist/ui/mcp.d.ts.map +1 -1
- package/dist/ui/mcp.js +8 -43
- package/dist/ui/mcp.js.map +1 -1
- package/dist/ui/pixel.d.ts.map +1 -1
- package/dist/ui/pixel.js +10 -38
- package/dist/ui/pixel.js.map +1 -1
- package/dist/ui/queued-message.test.js +7 -1
- package/dist/ui/queued-message.test.js.map +1 -1
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +154 -5
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/sessions.d.ts.map +1 -1
- package/dist/ui/sessions.js +10 -42
- package/dist/ui/sessions.js.map +1 -1
- package/dist/ui/startup-banner-order.test.d.ts +2 -0
- package/dist/ui/startup-banner-order.test.d.ts.map +1 -0
- package/dist/ui/startup-banner-order.test.js +105 -0
- package/dist/ui/startup-banner-order.test.js.map +1 -0
- package/dist/ui/streaming-flush-bounce.test.js +41 -20
- package/dist/ui/streaming-flush-bounce.test.js.map +1 -1
- package/dist/ui/submit-boundary-gap.test.d.ts +2 -0
- package/dist/ui/submit-boundary-gap.test.d.ts.map +1 -0
- package/dist/ui/submit-boundary-gap.test.js +180 -0
- package/dist/ui/submit-boundary-gap.test.js.map +1 -0
- package/dist/ui/terminal-history.d.ts.map +1 -1
- package/dist/ui/terminal-history.js +28 -9
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/terminal-history.test.js +10 -3
- package/dist/ui/terminal-history.test.js.map +1 -1
- package/dist/ui/testing/screen-recorder.d.ts.map +1 -1
- package/dist/ui/testing/screen-recorder.js +11 -1
- package/dist/ui/testing/screen-recorder.js.map +1 -1
- package/dist/ui/tui-history-parity.test.js +4 -1
- package/dist/ui/tui-history-parity.test.js.map +1 -1
- package/dist/ui/tui-simulation.test.js +7 -1
- package/dist/ui/tui-simulation.test.js.map +1 -1
- package/dist/ui/utils/assistant-stream-split.d.ts +7 -0
- package/dist/ui/utils/assistant-stream-split.d.ts.map +1 -1
- package/dist/ui/utils/assistant-stream-split.js +22 -1
- package/dist/ui/utils/assistant-stream-split.js.map +1 -1
- package/dist/ui/utils/assistant-stream-split.test.js +14 -0
- package/dist/ui/utils/assistant-stream-split.test.js.map +1 -1
- package/dist/ui/utils/markdown-renderer.d.ts.map +1 -1
- package/dist/ui/utils/markdown-renderer.js +46 -3
- package/dist/ui/utils/markdown-renderer.js.map +1 -1
- package/dist/ui/utils/markdown-renderer.test.d.ts +2 -0
- package/dist/ui/utils/markdown-renderer.test.d.ts.map +1 -0
- package/dist/ui/utils/markdown-renderer.test.js +63 -0
- package/dist/ui/utils/markdown-renderer.test.js.map +1 -0
- package/dist/ui/utils/terminal-graphics.d.ts +28 -1
- package/dist/ui/utils/terminal-graphics.d.ts.map +1 -1
- package/dist/ui/utils/terminal-graphics.js +44 -3
- package/dist/ui/utils/terminal-graphics.js.map +1 -1
- package/dist/ui/utils/terminal-graphics.test.js +40 -1
- package/dist/ui/utils/terminal-graphics.test.js.map +1 -1
- package/dist/utils/session-title.js +1 -1
- package/dist/utils/session-title.js.map +1 -1
- package/package.json +7 -6
- package/dist/core/model-registry.test.d.ts +0 -2
- package/dist/core/model-registry.test.d.ts.map +0 -1
- package/dist/core/model-registry.test.js +0 -95
- package/dist/core/model-registry.test.js.map +0 -1
- package/dist/core/oauth/gemini.test.d.ts +0 -2
- package/dist/core/oauth/gemini.test.d.ts.map +0 -1
- package/dist/core/oauth/gemini.test.js +0 -154
- package/dist/core/oauth/gemini.test.js.map +0 -1
- package/dist/core/thinking-level.test.d.ts +0 -2
- package/dist/core/thinking-level.test.d.ts.map +0 -1
- package/dist/core/thinking-level.test.js +0 -51
- package/dist/core/thinking-level.test.js.map +0 -1
- package/dist/core/voice-transcriber.test.d.ts +0 -2
- package/dist/core/voice-transcriber.test.d.ts.map +0 -1
- package/dist/core/voice-transcriber.test.js +0 -88
- package/dist/core/voice-transcriber.test.js.map +0 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Reproduction of the "large white space right before the final response".
|
|
3
|
+
//
|
|
4
|
+
// While the agent runs, the patched ink's bottom anchor converts every frame
|
|
5
|
+
// SHRINK into pad debt — blank lines emitted above the frame so the footer
|
|
6
|
+
// never moves up. That is correct mid-run: the next scrollback insert
|
|
7
|
+
// overwrites the pads (cursor-up consume). But when the RUN ENDS right after
|
|
8
|
+
// a shrink (live tool panel collapse, intermediate rows removed without a
|
|
9
|
+
// compensating insert), the leftover pads have nothing left to consume them:
|
|
10
|
+
// the anchor deactivates 500ms later and the blank block stays on screen,
|
|
11
|
+
// sitting exactly between the flushed transcript and the live final response.
|
|
12
|
+
//
|
|
13
|
+
// This test drives the real patched ink through that sequence and asserts the
|
|
14
|
+
// anchor deactivation reclaims the leftover pads (no blank gap above the
|
|
15
|
+
// frame, footer still bottom-pinned).
|
|
16
|
+
import React from "react";
|
|
17
|
+
import { Box, render, Text } from "ink";
|
|
18
|
+
import { describe, expect, it } from "vitest";
|
|
19
|
+
import stripAnsi from "strip-ansi";
|
|
20
|
+
import { ScreenRecorder, makeRecordingStdout } from "./testing/screen-recorder.js";
|
|
21
|
+
const COLUMNS = 60;
|
|
22
|
+
const ROWS = 24;
|
|
23
|
+
const FOOTER = "SIM_FOOTER_BOTTOM";
|
|
24
|
+
const FRAME_TOP = "SIM_FRAME_TOP";
|
|
25
|
+
function Frame({ liveRows }) {
|
|
26
|
+
return (_jsxs(Box, { flexDirection: "column", width: COLUMNS, children: [_jsx(Text, { children: FRAME_TOP }), Array.from({ length: liveRows }, (_, i) => (_jsxs(Text, { children: ["SIM_LIVE_", i + 1] }, i))), _jsx(Text, { children: "SIM_INPUT" }), _jsx(Text, { children: FOOTER })] }));
|
|
27
|
+
}
|
|
28
|
+
async function tick(ms = 60) {
|
|
29
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
30
|
+
}
|
|
31
|
+
describe("anchor pad reclaim on run end", () => {
|
|
32
|
+
it("leaves no blank gap above the frame after the anchor deactivates", async () => {
|
|
33
|
+
const recorder = new ScreenRecorder({ columns: COLUMNS, rows: ROWS });
|
|
34
|
+
const stdout = makeRecordingStdout(recorder);
|
|
35
|
+
const transcriptRows = Array.from({ length: ROWS }, (_, i) => `SIM_HISTORY_${i + 1}`);
|
|
36
|
+
const mounted = render(_jsx(Frame, { liveRows: 2 }), {
|
|
37
|
+
stdout,
|
|
38
|
+
patchConsole: false,
|
|
39
|
+
maxFps: 1000,
|
|
40
|
+
// Mirror renderApp's INK_OPTIONS — the pad/anchor machinery is opt-in.
|
|
41
|
+
anchorFrameToBottom: true,
|
|
42
|
+
clipFrameToTerminalHeight: true,
|
|
43
|
+
});
|
|
44
|
+
// Skip cleanly when running against unpatched ink (the APIs are fork-only).
|
|
45
|
+
if (!mounted.setFrameAnchorActive || !mounted.insertBeforeFrame) {
|
|
46
|
+
mounted.unmount();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// Mirrors renderApp's buildShrinkBackfill: last N transcript rows.
|
|
50
|
+
mounted.setFrameShrinkBackfill?.((needRows) => {
|
|
51
|
+
const lines = transcriptRows.slice(-needRows);
|
|
52
|
+
while (lines.length < needRows)
|
|
53
|
+
lines.unshift("");
|
|
54
|
+
return `${lines.join("\n")}\n`;
|
|
55
|
+
});
|
|
56
|
+
await tick();
|
|
57
|
+
// Turn starts: anchor on, transcript rows flushed to scrollback, live
|
|
58
|
+
// frame grows tall (streamed text + tool rows).
|
|
59
|
+
mounted.setFrameAnchorActive(true);
|
|
60
|
+
mounted.insertBeforeFrame(`${transcriptRows.join("\n")}\n`);
|
|
61
|
+
mounted.rerender(_jsx(Frame, { liveRows: 12 }));
|
|
62
|
+
await tick();
|
|
63
|
+
// Finalization shrink: intermediate live rows vanish with NO compensating
|
|
64
|
+
// scrollback insert. The anchor converts the shrink into pad debt — a
|
|
65
|
+
// blank block above the frame (correct mid-run: footer must not move).
|
|
66
|
+
mounted.rerender(_jsx(Frame, { liveRows: 2 }));
|
|
67
|
+
await tick();
|
|
68
|
+
// Run ends: App's 500ms timer deactivates the anchor. The leftover pads
|
|
69
|
+
// must be reclaimed here — nothing else will ever consume them at idle.
|
|
70
|
+
mounted.setFrameAnchorActive(false);
|
|
71
|
+
await tick(150);
|
|
72
|
+
const lines = recorder.viewportLines().map((line) => stripAnsi(line));
|
|
73
|
+
const frameTopIdx = lines.findIndex((line) => line.includes(FRAME_TOP));
|
|
74
|
+
const footerIdx = lines.findIndex((line) => line.includes(FOOTER));
|
|
75
|
+
expect(frameTopIdx, "live frame visible").toBeGreaterThanOrEqual(0);
|
|
76
|
+
expect(footerIdx, "footer visible").toBeGreaterThan(frameTopIdx);
|
|
77
|
+
// Nothing below the footer (footer not stranded above blanks).
|
|
78
|
+
const lastNonBlank = lines.reduce((acc, line, i) => (line.trim().length > 0 ? i : acc), -1);
|
|
79
|
+
expect(lastNonBlank, "nothing below the footer").toBe(footerIdx);
|
|
80
|
+
// THE BUG: no blank block above the frame. Every row between the last
|
|
81
|
+
// transcript row above the frame and the frame top must be non-blank.
|
|
82
|
+
const blanksAboveFrame = lines.slice(0, frameTopIdx).filter((line) => line.trim() === "");
|
|
83
|
+
expect(blanksAboveFrame.length, "no blank gap above the live frame").toBe(0);
|
|
84
|
+
mounted.unmount();
|
|
85
|
+
});
|
|
86
|
+
it("reclaims the leftover pads MID-RUN via an off→on pulse (no blank gap during a quiet stretch)", async () => {
|
|
87
|
+
const recorder = new ScreenRecorder({ columns: COLUMNS, rows: ROWS });
|
|
88
|
+
const stdout = makeRecordingStdout(recorder);
|
|
89
|
+
const transcriptRows = Array.from({ length: ROWS }, (_, i) => `SIM_HISTORY_${i + 1}`);
|
|
90
|
+
const mounted = render(_jsx(Frame, { liveRows: 2 }), {
|
|
91
|
+
stdout,
|
|
92
|
+
patchConsole: false,
|
|
93
|
+
maxFps: 1000,
|
|
94
|
+
anchorFrameToBottom: true,
|
|
95
|
+
clipFrameToTerminalHeight: true,
|
|
96
|
+
});
|
|
97
|
+
if (!mounted.setFrameAnchorActive || !mounted.insertBeforeFrame) {
|
|
98
|
+
mounted.unmount();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
mounted.setFrameShrinkBackfill?.((needRows) => {
|
|
102
|
+
const lines = transcriptRows.slice(-needRows);
|
|
103
|
+
while (lines.length < needRows)
|
|
104
|
+
lines.unshift("");
|
|
105
|
+
return `${lines.join("\n")}\n`;
|
|
106
|
+
});
|
|
107
|
+
await tick();
|
|
108
|
+
// Turn starts: anchor on, transcript flushed, frame grows tall.
|
|
109
|
+
mounted.setFrameAnchorActive(true);
|
|
110
|
+
mounted.insertBeforeFrame(`${transcriptRows.join("\n")}\n`);
|
|
111
|
+
mounted.rerender(_jsx(Frame, { liveRows: 12 }));
|
|
112
|
+
await tick();
|
|
113
|
+
// Tool batch finished, frame shrinks with NO compensating insert: pad debt
|
|
114
|
+
// forms (correct mid-run). Then the agent goes quiet (long thinking phase)
|
|
115
|
+
// — nothing grows the frame to consume the pads, so the blank gap lingers.
|
|
116
|
+
mounted.rerender(_jsx(Frame, { liveRows: 2 }));
|
|
117
|
+
await tick();
|
|
118
|
+
// App's mid-run debounce fires while the run is STILL active: an off→on
|
|
119
|
+
// pulse. The off transition reclaims the pad debt (gap closes, footer stays
|
|
120
|
+
// pinned); the on transition immediately restores pad protection.
|
|
121
|
+
mounted.setFrameAnchorActive(false);
|
|
122
|
+
mounted.setFrameAnchorActive(true);
|
|
123
|
+
await tick(150);
|
|
124
|
+
const lines = recorder.viewportLines().map((line) => stripAnsi(line));
|
|
125
|
+
const frameTopIdx = lines.findIndex((line) => line.includes(FRAME_TOP));
|
|
126
|
+
const footerIdx = lines.findIndex((line) => line.includes(FOOTER));
|
|
127
|
+
expect(frameTopIdx, "live frame visible").toBeGreaterThanOrEqual(0);
|
|
128
|
+
expect(footerIdx, "footer visible").toBeGreaterThan(frameTopIdx);
|
|
129
|
+
const lastNonBlank = lines.reduce((acc, line, i) => (line.trim().length > 0 ? i : acc), -1);
|
|
130
|
+
expect(lastNonBlank, "nothing below the footer").toBe(footerIdx);
|
|
131
|
+
const blanksAboveFrame = lines.slice(0, frameTopIdx).filter((line) => line.trim() === "");
|
|
132
|
+
expect(blanksAboveFrame.length, "no blank gap above the live frame after mid-run pulse").toBe(0);
|
|
133
|
+
// The pulse left the anchor ACTIVE: a further shrink must still pad so the
|
|
134
|
+
// footer does not move UP, proving protection was restored, not disabled.
|
|
135
|
+
mounted.rerender(_jsx(Frame, { liveRows: 1 }));
|
|
136
|
+
await tick();
|
|
137
|
+
const afterLines = recorder.viewportLines().map((line) => stripAnsi(line));
|
|
138
|
+
const afterFooterIdx = afterLines.findIndex((line) => line.includes(FOOTER));
|
|
139
|
+
expect(afterFooterIdx, "footer still visible after a post-pulse shrink").toBeGreaterThan(0);
|
|
140
|
+
expect(afterFooterIdx, "footer did not rise after a post-pulse shrink (anchor still active)").toBeGreaterThanOrEqual(footerIdx);
|
|
141
|
+
const afterLastNonBlank = afterLines.reduce((acc, line, i) => (line.trim().length > 0 ? i : acc), -1);
|
|
142
|
+
expect(afterLastNonBlank, "nothing below the footer after a post-pulse shrink").toBe(afterFooterIdx);
|
|
143
|
+
mounted.unmount();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=anchor-pad-reclaim.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchor-pad-reclaim.test.js","sourceRoot":"","sources":["../../src/ui/anchor-pad-reclaim.test.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/app-items.d.ts
CHANGED
|
@@ -275,4 +275,18 @@ export declare function lastVisibleTranscriptItem<T extends {
|
|
|
275
275
|
imagePreviews?: readonly unknown[];
|
|
276
276
|
}>(items: readonly T[]): T | undefined;
|
|
277
277
|
export type CompletedItem = UserItem | TaskItem | GoalAgentTransitionItem | GoalProgressItem | AssistantItem | IdealHookItem | ToolStartItem | ToolDoneItem | ServerToolStartItem | ServerToolDoneItem | ErrorItem | InfoItem | StylePackItem | SetupHintItem | UpdateNoticeItem | QueuedItem | CompactingItem | CompactedItem | DurationItem | SessionSummaryItem | BannerItem | SubAgentGroupItem | ToolGroupItem | PlanTransitionItem | ModelTransitionItem | ThemeTransitionItem | PlanEventItem | StoppedItem | TombstoneItem | StepDoneItem;
|
|
278
|
+
/**
|
|
279
|
+
* True when a transcript item carries one or more inline-image previews.
|
|
280
|
+
*
|
|
281
|
+
* Used to detect images in a transcript region before the bottom-anchor shrink
|
|
282
|
+
* backfill tries to reconstruct it as text. A graphics escape's base64 payload
|
|
283
|
+
* is not recognized as zero-width by `wrapAnsi` (it hard-wraps into literal
|
|
284
|
+
* base64 text) and its visual row count never matches its newline count, so a
|
|
285
|
+
* text-only repaint of an image region desyncs Ink's erase math and displaces
|
|
286
|
+
* the on-screen image. Callers bail out of the text repaint when this is true.
|
|
287
|
+
*/
|
|
288
|
+
export declare function itemHasImagePreviews(item: {
|
|
289
|
+
kind: string;
|
|
290
|
+
imagePreviews?: readonly unknown[];
|
|
291
|
+
}): boolean;
|
|
278
292
|
//# sourceMappingURL=app-items.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-items.d.ts","sourceRoot":"","sources":["../../src/ui/app-items.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-items.d.ts","sourceRoot":"","sources":["../../src/ui/app-items.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/app-items.js
CHANGED
|
@@ -58,4 +58,17 @@ export function lastVisibleTranscriptItem(items) {
|
|
|
58
58
|
}
|
|
59
59
|
return undefined;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* True when a transcript item carries one or more inline-image previews.
|
|
63
|
+
*
|
|
64
|
+
* Used to detect images in a transcript region before the bottom-anchor shrink
|
|
65
|
+
* backfill tries to reconstruct it as text. A graphics escape's base64 payload
|
|
66
|
+
* is not recognized as zero-width by `wrapAnsi` (it hard-wraps into literal
|
|
67
|
+
* base64 text) and its visual row count never matches its newline count, so a
|
|
68
|
+
* text-only repaint of an image region desyncs Ink's erase math and displaces
|
|
69
|
+
* the on-screen image. Callers bail out of the text repaint when this is true.
|
|
70
|
+
*/
|
|
71
|
+
export function itemHasImagePreviews(item) {
|
|
72
|
+
return !!(item.imagePreviews && item.imagePreviews.length > 0);
|
|
73
|
+
}
|
|
61
74
|
//# sourceMappingURL=app-items.js.map
|
package/dist/ui/app-items.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-items.js","sourceRoot":"","sources":["../../src/ui/app-items.ts"],"names":[],"mappings":"AAiIA,MAAM,CAAC,MAAM,kBAAkB,GAAG,wCAAwC,CAAC;AAE3E,yEAAyE;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,2DAA2D,CAAC;AAElG,iFAAiF;AACjF,MAAM,CAAC,MAAM,sBAAsB,GACjC,mEAAmE,CAAC;AAEtE,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAClC,uEAAuE,CAAC;AAY1E;gEACgE;AAChE,MAAM,CAAC,MAAM,eAAe,GAA0D;IACpF,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,SAAS;CAChB,CAAC;AAsJF;;;;;;;;;;;GAWG;AACH,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAS;IAChD,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,mBAAmB;IACnB,kBAAkB;CACnB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAGvC;IACC,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CAEvC,KAAmB;IACnB,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC1D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"app-items.js","sourceRoot":"","sources":["../../src/ui/app-items.ts"],"names":[],"mappings":"AAiIA,MAAM,CAAC,MAAM,kBAAkB,GAAG,wCAAwC,CAAC;AAE3E,yEAAyE;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,2DAA2D,CAAC;AAElG,iFAAiF;AACjF,MAAM,CAAC,MAAM,sBAAsB,GACjC,mEAAmE,CAAC;AAEtE,iFAAiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAClC,uEAAuE,CAAC;AAY1E;gEACgE;AAChE,MAAM,CAAC,MAAM,eAAe,GAA0D;IACpF,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,SAAS;CAChB,CAAC;AAsJF;;;;;;;;;;;GAWG;AACH,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAS;IAChD,YAAY;IACZ,WAAW;IACX,YAAY;IACZ,mBAAmB;IACnB,kBAAkB;CACnB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAGvC;IACC,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CAEvC,KAAmB;IACnB,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IAC1D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAkCD;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAGpC;IACC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { lastVisibleTranscriptItem } from "./app-items.js";
|
|
2
|
+
import { lastVisibleTranscriptItem, itemHasImagePreviews } from "./app-items.js";
|
|
3
3
|
describe("lastVisibleTranscriptItem", () => {
|
|
4
4
|
it("returns the last item when nothing is panel-replaced", () => {
|
|
5
5
|
const items = [
|
|
@@ -35,4 +35,20 @@ describe("lastVisibleTranscriptItem", () => {
|
|
|
35
35
|
expect(lastVisibleTranscriptItem([])).toBeUndefined();
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
|
+
describe("itemHasImagePreviews", () => {
|
|
39
|
+
it("is true for items carrying image previews", () => {
|
|
40
|
+
expect(itemHasImagePreviews({ kind: "user", imagePreviews: [{ base64: "AAAA" }] })).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
it("is false for items with no previews or an empty list", () => {
|
|
43
|
+
expect(itemHasImagePreviews({ kind: "assistant" })).toBe(false);
|
|
44
|
+
expect(itemHasImagePreviews({ kind: "tool_done", imagePreviews: [] })).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
it("detects an image anywhere in a transcript via some()", () => {
|
|
47
|
+
const history = [
|
|
48
|
+
{ kind: "assistant", imagePreviews: undefined },
|
|
49
|
+
{ kind: "user", imagePreviews: [{ base64: "x" }] },
|
|
50
|
+
];
|
|
51
|
+
expect(history.some(itemHasImagePreviews)).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
38
54
|
//# sourceMappingURL=app-items.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-items.test.js","sourceRoot":"","sources":["../../src/ui/app-items.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"app-items.test.js","sourceRoot":"","sources":["../../src/ui/app-items.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-flush-regression.test.d.ts","sourceRoot":"","sources":["../../src/ui/atomic-flush-regression.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Full-lifecycle regression for the atomic transcript flush.
|
|
3
|
+
//
|
|
4
|
+
// Models a complete turn on the native-scrollback default: idle → tall
|
|
5
|
+
// streaming response → live tool panel grows under the controls → done. The
|
|
6
|
+
// done transition finalizes the turn the way App does: queueFlush renders the
|
|
7
|
+
// transcript to ANSI and enqueues it through the patched Ink
|
|
8
|
+
// `insertBeforeFrame` while — in the SAME React batch — the live frame shrinks
|
|
9
|
+
// (streamed text flushed, tool panel hidden, activity → done swap). The
|
|
10
|
+
// resulting single frame write is `erase tall frame + scrollback bytes +
|
|
11
|
+
// shorter frame`, so:
|
|
12
|
+
// (a) Ink's full-screen repaint (eraseScreen + cursorTo top) never fires,
|
|
13
|
+
// (b) the footer never moves UP in the terminal buffer, and
|
|
14
|
+
// (c) the controls sit directly under the last transcript row after done —
|
|
15
|
+
// no stranded blank gap.
|
|
16
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
17
|
+
import { render, Text, useStdout } from "ink";
|
|
18
|
+
import { describe, expect, it } from "vitest";
|
|
19
|
+
import stripAnsi from "strip-ansi";
|
|
20
|
+
import { ChatControls, ChatLayout } from "./components/ChatLayout.js";
|
|
21
|
+
import { ChatLivePane } from "./components/ChatLivePane.js";
|
|
22
|
+
import { TerminalSizeProvider } from "./hooks/useTerminalSize.js";
|
|
23
|
+
import { renderTranscriptItem } from "./transcript/TranscriptRenderer.js";
|
|
24
|
+
import { loadTheme, ThemeContext } from "./theme/theme.js";
|
|
25
|
+
import { createTerminalHistoryPrinter } from "./terminal-history.js";
|
|
26
|
+
import { useTranscriptHistory } from "./hooks/useTranscriptHistory.js";
|
|
27
|
+
import { ScreenRecorder, makeRecordingStdout } from "./testing/screen-recorder.js";
|
|
28
|
+
const COLUMNS = 80;
|
|
29
|
+
const ROWS = 24;
|
|
30
|
+
const theme = loadTheme("dark");
|
|
31
|
+
const terminalContext = {
|
|
32
|
+
theme,
|
|
33
|
+
columns: COLUMNS,
|
|
34
|
+
version: "sim",
|
|
35
|
+
model: "sim-model",
|
|
36
|
+
provider: "anthropic",
|
|
37
|
+
cwd: "/tmp/sim-project",
|
|
38
|
+
};
|
|
39
|
+
const FOOTER_BOTTOM = "SIM_ACTIVITY_BAR";
|
|
40
|
+
const TOOL_PANEL_ROWS = 4;
|
|
41
|
+
// Live-area budget: terminal rows minus the worst-case controls block (tool
|
|
42
|
+
// panel + status + input + footer rows). Mirrors App's layout measurement —
|
|
43
|
+
// the clamp is what keeps Ink out of its full-screen tall-frame repaint path.
|
|
44
|
+
const LIVE_AREA_BUDGET = ROWS - (TOOL_PANEL_ROWS + 4) - 2;
|
|
45
|
+
// Taller than the live-area budget, so streaming engages the clamp and the
|
|
46
|
+
// final flush writes more scrollback rows than the live region ever showed.
|
|
47
|
+
const longResponse = Array.from({ length: ROWS - 6 }, (_, i) => `SIM_LINE_${String(i + 1).padStart(2, "0")}`).join("\n");
|
|
48
|
+
function SimulatedControls({ running, toolRows }) {
|
|
49
|
+
return (_jsxs(ChatControls, { controlsRef: () => { }, children: [Array.from({ length: toolRows }, (_, i) => (_jsx(Text, { children: `SIM_TOOL_${i + 1}` }, `tool-${i}`))), _jsx(Text, { children: running ? "SIM_STREAMING" : "SIM_DONE" }), _jsx(Text, { children: "SIM_INPUT" }), _jsx(Text, { children: "SIM_FOOTER" }), _jsx(Text, { children: FOOTER_BOTTOM })] }));
|
|
50
|
+
}
|
|
51
|
+
function Driver({ phase, enqueueStdout }) {
|
|
52
|
+
const { write: writeStdout } = useStdout();
|
|
53
|
+
const [history, setHistory] = useState([]);
|
|
54
|
+
const [liveItems, setLiveItems] = useState([]);
|
|
55
|
+
// All visuals derive from internal state so the done transition can swap
|
|
56
|
+
// EVERYTHING (flush + streamed text removal + panel hide + activity → done)
|
|
57
|
+
// in one effect — i.e. one React batch — exactly like useAgentLoop's onDone.
|
|
58
|
+
const [view, setView] = useState({ running: false, streamingText: "", toolRows: 0 });
|
|
59
|
+
const committedRef = useRef(false);
|
|
60
|
+
// Stable printer across renders — mirrors renderApp, where one printer
|
|
61
|
+
// instance (and its printed-id dedup set) lives for the whole app lifetime.
|
|
62
|
+
const printerRef = useRef(null);
|
|
63
|
+
printerRef.current ??= createTerminalHistoryPrinter();
|
|
64
|
+
const { queueFlush } = useTranscriptHistory({
|
|
65
|
+
terminalHistoryPrinter: printerRef.current,
|
|
66
|
+
terminalHistoryContext: terminalContext,
|
|
67
|
+
writeStdout,
|
|
68
|
+
enqueueStdout,
|
|
69
|
+
sessionPathRef: { current: undefined },
|
|
70
|
+
sessionManagerRef: { current: null },
|
|
71
|
+
history,
|
|
72
|
+
setHistory,
|
|
73
|
+
setLiveItems,
|
|
74
|
+
});
|
|
75
|
+
// Idempotent setter: queueFlush is referentially unstable across renders
|
|
76
|
+
// (it lives in the hook's render scope), so this effect re-runs every
|
|
77
|
+
// commit. Returning the previous object when nothing changed keeps React
|
|
78
|
+
// from looping ("Maximum update depth exceeded") on the stream/tools
|
|
79
|
+
// phases, which set the same view on every run.
|
|
80
|
+
const applyView = (next) => {
|
|
81
|
+
setView((prev) => prev.running === next.running &&
|
|
82
|
+
prev.streamingText === next.streamingText &&
|
|
83
|
+
prev.toolRows === next.toolRows
|
|
84
|
+
? prev
|
|
85
|
+
: next);
|
|
86
|
+
};
|
|
87
|
+
const applyViewRef = useRef(applyView);
|
|
88
|
+
applyViewRef.current = applyView;
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (phase === "idle")
|
|
91
|
+
return;
|
|
92
|
+
if (phase === "stream") {
|
|
93
|
+
applyViewRef.current({ running: true, streamingText: longResponse, toolRows: 0 });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (phase === "tools") {
|
|
97
|
+
applyViewRef.current({
|
|
98
|
+
running: true,
|
|
99
|
+
streamingText: longResponse,
|
|
100
|
+
toolRows: TOOL_PANEL_ROWS,
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (committedRef.current)
|
|
105
|
+
return;
|
|
106
|
+
committedRef.current = true;
|
|
107
|
+
// Finalize the turn: enqueue the transcript bytes (passive) and shrink the
|
|
108
|
+
// live frame in the same batch. The next frame write carries both.
|
|
109
|
+
queueFlush([{ kind: "assistant", id: "final", text: longResponse }]);
|
|
110
|
+
setLiveItems([]);
|
|
111
|
+
applyViewRef.current({ running: false, streamingText: "", toolRows: 0 });
|
|
112
|
+
}, [phase, queueFlush]);
|
|
113
|
+
const renderItem = (item, index, items) => renderTranscriptItem({
|
|
114
|
+
item,
|
|
115
|
+
index,
|
|
116
|
+
items,
|
|
117
|
+
version: "sim",
|
|
118
|
+
currentModel: "sim-model",
|
|
119
|
+
currentProvider: "anthropic",
|
|
120
|
+
displayedCwd: "/tmp/sim-project",
|
|
121
|
+
columns: COLUMNS,
|
|
122
|
+
theme,
|
|
123
|
+
renderMarkdown: true,
|
|
124
|
+
measuredLiveAreaRows: LIVE_AREA_BUDGET,
|
|
125
|
+
});
|
|
126
|
+
return (_jsx(ThemeContext.Provider, { value: theme, children: _jsx(TerminalSizeProvider, { children: _jsxs(ChatLayout, { columns: COLUMNS, children: [_jsx(ChatLivePane, { liveItems: liveItems, renderItem: renderItem, isRunning: view.running, visibleStreamingText: view.streamingText, streamingThinking: "", thinkingMs: 0, reserveStreamingSpacing: false, renderMarkdown: true, measuredLiveAreaRows: LIVE_AREA_BUDGET, assistantMarginTop: 0, streamingContinuation: false }), _jsx(SimulatedControls, { running: view.running, toolRows: view.toolRows })] }) }) }));
|
|
127
|
+
}
|
|
128
|
+
const ERASE_SCREEN = "\u001B[2J";
|
|
129
|
+
async function tick() {
|
|
130
|
+
await new Promise((resolve) => setTimeout(resolve, 45));
|
|
131
|
+
}
|
|
132
|
+
describe("atomic transcript flush lifecycle", () => {
|
|
133
|
+
it("finalizes a tool-heavy turn without repaints, footer rises, or gaps", async () => {
|
|
134
|
+
const recorder = new ScreenRecorder({ columns: COLUMNS, rows: ROWS });
|
|
135
|
+
const baseStdout = makeRecordingStdout(recorder);
|
|
136
|
+
const sink = { raw: "" };
|
|
137
|
+
const stdout = new Proxy(baseStdout, {
|
|
138
|
+
get(target, prop, receiver) {
|
|
139
|
+
if (prop === "write") {
|
|
140
|
+
return (chunk, cb) => {
|
|
141
|
+
sink.raw += chunk;
|
|
142
|
+
return target.write(chunk, cb);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return Reflect.get(target, prop, receiver);
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
// Mirrors renderApp's enqueueHistoryWrite: read the (patched) instance at
|
|
149
|
+
// call time, fall back to a raw write when the API is unavailable.
|
|
150
|
+
const instanceRef = {
|
|
151
|
+
current: null,
|
|
152
|
+
};
|
|
153
|
+
const enqueueStdout = (data) => {
|
|
154
|
+
if (instanceRef.current?.insertBeforeFrame) {
|
|
155
|
+
instanceRef.current.insertBeforeFrame(data);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
stdout.write(data);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const frames = [];
|
|
162
|
+
const capture = (label) => {
|
|
163
|
+
frames.push({ label, full: stripAnsi(recorder.fullText()) });
|
|
164
|
+
};
|
|
165
|
+
const mounted = render(_jsx(Driver, { phase: "idle", enqueueStdout: enqueueStdout }), {
|
|
166
|
+
stdout,
|
|
167
|
+
columns: COLUMNS,
|
|
168
|
+
rows: ROWS,
|
|
169
|
+
patchConsole: false,
|
|
170
|
+
maxFps: 1000,
|
|
171
|
+
});
|
|
172
|
+
instanceRef.current = mounted;
|
|
173
|
+
await tick();
|
|
174
|
+
capture("idle");
|
|
175
|
+
mounted.rerender(_jsx(Driver, { phase: "stream", enqueueStdout: enqueueStdout }));
|
|
176
|
+
await tick();
|
|
177
|
+
capture("tall streaming");
|
|
178
|
+
mounted.rerender(_jsx(Driver, { phase: "tools", enqueueStdout: enqueueStdout }));
|
|
179
|
+
await tick();
|
|
180
|
+
capture("tool panel grows");
|
|
181
|
+
mounted.rerender(_jsx(Driver, { phase: "done", enqueueStdout: enqueueStdout }));
|
|
182
|
+
await tick();
|
|
183
|
+
capture("done, first settle");
|
|
184
|
+
await tick();
|
|
185
|
+
capture("done, settled");
|
|
186
|
+
mounted.unmount();
|
|
187
|
+
// (a) Zero full-screen repaints (eraseScreen + cursorTo top) across the
|
|
188
|
+
// whole lifecycle — the clamp keeps Ink out of its tall-frame path, and
|
|
189
|
+
// the atomic insert keeps the shrink from ever needing a repaint.
|
|
190
|
+
expect(sink.raw.split(ERASE_SCREEN).length - 1, "full-screen repaints").toBe(0);
|
|
191
|
+
// (b) The footer's absolute row in the terminal buffer never moves UP.
|
|
192
|
+
// Scrollback growth pushes it down; an upward move means a shrink-write
|
|
193
|
+
// landed without its compensating scrollback bytes.
|
|
194
|
+
let previousFooterRow = -1;
|
|
195
|
+
for (const f of frames) {
|
|
196
|
+
const footerRow = f.full.split("\n").findIndex((line) => line.includes(FOOTER_BOTTOM));
|
|
197
|
+
expect(footerRow, `${f.label}: footer present`).toBeGreaterThanOrEqual(0);
|
|
198
|
+
expect(footerRow, `${f.label}: footer buffer row never decreases (was ${previousFooterRow})`).toBeGreaterThanOrEqual(previousFooterRow);
|
|
199
|
+
previousFooterRow = footerRow;
|
|
200
|
+
}
|
|
201
|
+
// (c) After done: the controls sit directly under the last transcript row —
|
|
202
|
+
// no stranded blank rows between the flushed response and the controls.
|
|
203
|
+
const settled = frames.at(-1);
|
|
204
|
+
const lines = settled.full.split("\n");
|
|
205
|
+
const lastTranscriptRow = lines.reduce((acc, line, i) => (line.includes("SIM_LINE_") ? i : acc), -1);
|
|
206
|
+
const controlsRow = lines.findIndex((line) => line.includes("SIM_DONE"));
|
|
207
|
+
expect(lastTranscriptRow, "flushed transcript present after done").toBeGreaterThanOrEqual(0);
|
|
208
|
+
expect(controlsRow, "controls present after done").toBeGreaterThan(lastTranscriptRow);
|
|
209
|
+
const between = lines.slice(lastTranscriptRow + 1, controlsRow);
|
|
210
|
+
expect(between.filter((line) => line.trim().length === 0).length, "no blank gap between transcript and controls").toBe(0);
|
|
211
|
+
// And the flushed response must never be duplicated (scrollback + live).
|
|
212
|
+
for (const f of frames) {
|
|
213
|
+
const occurrences = f.full.split("SIM_LINE_01").length - 1;
|
|
214
|
+
expect(occurrences, `${f.label}: flushed content not duplicated`).toBeLessThanOrEqual(1);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
//# sourceMappingURL=atomic-flush-regression.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-flush-regression.test.js","sourceRoot":"","sources":["../../src/ui/atomic-flush-regression.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { Box, render, renderToString } from "ink";
|
|
4
|
-
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
5
5
|
import stringWidth from "string-width";
|
|
6
6
|
import stripAnsi from "strip-ansi";
|
|
7
7
|
import { AssistantMessage } from "./AssistantMessage.js";
|
|
@@ -10,6 +10,12 @@ import { ToolExecution } from "./ToolExecution.js";
|
|
|
10
10
|
import { ToolGroupExecution } from "./ToolGroupExecution.js";
|
|
11
11
|
import { ServerToolExecution } from "./ServerToolExecution.js";
|
|
12
12
|
import { TerminalSizeProvider } from "../hooks/useTerminalSize.js";
|
|
13
|
+
// BLACK_CIRCLE is platform-dependent (⏺ on macOS, ● elsewhere); pin it so
|
|
14
|
+
// the hardcoded frame expectations pass on Linux/Windows CI too.
|
|
15
|
+
vi.mock("../constants/figures.js", async (importOriginal) => ({
|
|
16
|
+
...(await importOriginal()),
|
|
17
|
+
BLACK_CIRCLE: "\u23FA",
|
|
18
|
+
}));
|
|
13
19
|
import { createTerminalHistoryPrinter, serializeCompletedItemToTerminalHistory, } from "../terminal-history.js";
|
|
14
20
|
import { loadTheme } from "../theme/theme.js";
|
|
15
21
|
import { pinStreamingTextBeforeToolBoundary, shouldTopSpaceAssistantAfterToolBoundary, shouldTopSpaceStreamingAssistant, } from "../App.js";
|
|
@@ -61,6 +67,22 @@ function renderWithTerminal(element) {
|
|
|
61
67
|
function renderAssistantFrame(streaming, text = LONG_STREAMING_TEXT) {
|
|
62
68
|
return renderWithTerminal(_jsx(AssistantMessage, { text: text, streaming: streaming }));
|
|
63
69
|
}
|
|
70
|
+
/** Like renderWithTerminal but keeps blank rows — needed for alignment checks. */
|
|
71
|
+
function renderWithTerminalRaw(element) {
|
|
72
|
+
const originalColumns = process.stdout.columns;
|
|
73
|
+
const originalRows = process.stdout.rows;
|
|
74
|
+
process.stdout.columns = TERMINAL_COLUMNS;
|
|
75
|
+
process.stdout.rows = 20;
|
|
76
|
+
try {
|
|
77
|
+
return rawLinesOf(renderToString(_jsx(TerminalSizeProvider, { children: element }), {
|
|
78
|
+
columns: TERMINAL_COLUMNS,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
process.stdout.columns = originalColumns;
|
|
83
|
+
process.stdout.rows = originalRows;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
64
86
|
function renderTerminalHistoryAssistantText(text = LONG_STREAMING_TEXT) {
|
|
65
87
|
return serializeCompletedItemToTerminalHistory({ kind: "assistant", text, id: "assistant-1" }, {
|
|
66
88
|
theme: loadTheme("dark"),
|
|
@@ -218,6 +240,15 @@ describe("AssistantMessage live layout", () => {
|
|
|
218
240
|
const lines = renderWithTerminal(_jsx(AssistantMessage, { text: text, streaming: true, availableTerminalHeight: 5 }));
|
|
219
241
|
expect(lines.length).toBeLessThanOrEqual(5);
|
|
220
242
|
});
|
|
243
|
+
it("REGRESSION: dot stays inline when the height clamp slices at a blank line", () => {
|
|
244
|
+
// 3 paragraphs render as [p1, "", p2, "", p3]. availableTerminalHeight=4
|
|
245
|
+
// tail-slices to ["", p2, "", p3] — the ⏺ prefix sits in a sibling box
|
|
246
|
+
// aligned to the first row, so a leading blank row left the dot floating
|
|
247
|
+
// one row above the text (alignment varied with the slice boundary).
|
|
248
|
+
const text = "First paragraph here.\n\nSecond paragraph here.\n\nThird paragraph here.";
|
|
249
|
+
const lines = renderWithTerminalRaw(_jsx(AssistantMessage, { text: text, availableTerminalHeight: 4 }));
|
|
250
|
+
expect(lines[0]).toBe(" \u23FA Second paragraph here.");
|
|
251
|
+
});
|
|
221
252
|
it("renders the streaming frame with the same line structure as finalized history", () => {
|
|
222
253
|
const streamingLines = renderAssistantFrame(true);
|
|
223
254
|
const finalLines = renderAssistantFrame(false);
|