@kenkaiiii/ggcoder 4.8.2 → 4.8.4
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/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/ui/App.d.ts +16 -0
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +53 -16
- package/dist/ui/App.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 +25 -0
- package/dist/ui/components/AssistantMessage.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 +34 -19
- package/dist/ui/hooks/useTranscriptHistory.js.map +1 -1
- package/dist/ui/live-item-flush.d.ts +21 -0
- package/dist/ui/live-item-flush.d.ts.map +1 -1
- package/dist/ui/live-item-flush.js +35 -0
- package/dist/ui/live-item-flush.js.map +1 -1
- package/dist/ui/live-item-flush.test.js +72 -1
- package/dist/ui/live-item-flush.test.js.map +1 -1
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +126 -1
- package/dist/ui/render.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/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/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-commands.d.ts","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,eAAe,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"prompt-commands.d.ts","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,eAAe,EAAE,aAAa,EAsmB1C,CAAC;AAEF,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAExE"}
|
|
@@ -342,7 +342,7 @@ End your reply with this exact notice so the user doesn't miss it:
|
|
|
342
342
|
name: "setup-commit",
|
|
343
343
|
aliases: [],
|
|
344
344
|
description: "Generate a /commit command",
|
|
345
|
-
prompt: `Detect the project type and generate a /commit command that enforces quality checks before committing.
|
|
345
|
+
prompt: `Detect the project type and generate a /commit command that enforces quality checks and an agent code review before committing.
|
|
346
346
|
|
|
347
347
|
## Step 1: Detect Project and Extract Commands
|
|
348
348
|
|
|
@@ -361,7 +361,7 @@ Create the directory \`.gg/commands/\` if it doesn't exist, then write \`.gg/com
|
|
|
361
361
|
\`\`\`markdown
|
|
362
362
|
---
|
|
363
363
|
name: commit
|
|
364
|
-
description: Run checks, commit with AI message, and push
|
|
364
|
+
description: Run checks, agent code review, commit with AI message, and push
|
|
365
365
|
---
|
|
366
366
|
|
|
367
367
|
1. Run quality checks:
|
|
@@ -370,24 +370,37 @@ description: Run checks, commit with AI message, and push
|
|
|
370
370
|
|
|
371
371
|
2. Review changes: run git status and git diff --staged and git diff
|
|
372
372
|
|
|
373
|
-
3.
|
|
373
|
+
3. Fast review gate: spawn ONE subagent with the full diff. Instructions: review ONLY
|
|
374
|
+
the diff for real bugs, regressions, leftover debug code, and unintended changes.
|
|
375
|
+
Score each issue 0-100 confidence (pre-existing issues and stylistic nitpicks = false
|
|
376
|
+
positives, score low). Report ONLY issues with confidence >= 80, with file:line and a
|
|
377
|
+
one-line fix. If none, reply "CLEAR". This is a last check, not a deep audit - be fast.
|
|
374
378
|
|
|
375
|
-
4.
|
|
379
|
+
4. If CLEAR: proceed straight to step 5 and push WITHOUT asking the user anything.
|
|
380
|
+
If issues >= 80 were reported: STOP, show the issues, and ask exactly:
|
|
381
|
+
"Want me to fix this first, or commit and push anyway?
|
|
382
|
+
A) Fix it first, then commit & push
|
|
383
|
+
B) Commit & push anyway"
|
|
384
|
+
On A: fix, re-run step 1, then continue (no re-review). On B: continue as-is.
|
|
385
|
+
|
|
386
|
+
5. Stage relevant files with git add (specific files, not -A)
|
|
387
|
+
|
|
388
|
+
6. Generate a commit message:
|
|
376
389
|
- Start with verb (Add/Update/Fix/Remove/Refactor)
|
|
377
390
|
- Be specific and concise, one line preferred
|
|
378
391
|
|
|
379
|
-
|
|
392
|
+
7. Commit AND push in one go - never pause for confirmation here:
|
|
380
393
|
git commit -m "your generated message"
|
|
381
394
|
git push
|
|
382
395
|
\`\`\`
|
|
383
396
|
|
|
384
397
|
Replace [PROJECT-SPECIFIC LINT/TYPECHECK COMMANDS] with the actual commands.
|
|
385
398
|
|
|
386
|
-
Keep the command file under
|
|
399
|
+
Keep the command file under 30 lines.
|
|
387
400
|
|
|
388
401
|
## Step 3: Confirm
|
|
389
402
|
|
|
390
|
-
Report that /commit is now available with quality checks and AI-generated commit messages, and mention which local scripts/docs verified the commands.`,
|
|
403
|
+
Report that /commit is now available with quality checks, an agent code review gate, and AI-generated commit messages, and mention which local scripts/docs verified the commands.`,
|
|
391
404
|
},
|
|
392
405
|
{
|
|
393
406
|
name: "compare",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-commands.js","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,mCAAmC;QAChD,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0KA4E8J;KACvK;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,CAAC,IAAI,CAAC;QACf,WAAW,EAAE,8BAA8B;QAC3C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qEAsLyD;KAClE;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,+CAA+C;QAC5D,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2MA2D+L;KACxM;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,4BAA4B;QACzC,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"prompt-commands.js","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,mCAAmC;QAChD,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0KA4E8J;KACvK;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,CAAC,IAAI,CAAC;QACf,WAAW,EAAE,8BAA8B;QAC3C,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qEAsLyD;KAClE;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,+CAA+C;QAC5D,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2MA2D+L;KACxM;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,4BAA4B;QACzC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mLA0DuK;KAChL;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,yBAAyB;QACtC,MAAM,EAAE;;;;;;;;;;;;;;;iFAeqE;KAC9E;IACD;QACE,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,yBAAyB;QACtC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gLA6FoK;KAC7K;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,CAAC,eAAe,CAAC;QAC1B,WAAW,EAAE,qBAAqB;QAClC,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6JAwFiJ;KAC1J;CACF,CAAC;AAEF,gDAAgD;AAChD,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACxF,CAAC"}
|
package/dist/ui/App.d.ts
CHANGED
|
@@ -65,6 +65,22 @@ export interface AppProps {
|
|
|
65
65
|
onExitPlan?: (planPath: string) => Promise<string>;
|
|
66
66
|
};
|
|
67
67
|
terminalHistoryPrinter?: TerminalHistoryPrinter;
|
|
68
|
+
/**
|
|
69
|
+
* Wired by `renderApp`. Queues raw bytes through the patched Ink
|
|
70
|
+
* `insertBeforeFrame` so finalized transcript rows are folded atomically
|
|
71
|
+
* into the next frame write (erase old frame + scrollback bytes + new frame
|
|
72
|
+
* in one synchronized write). This is what keeps the footer pinned when
|
|
73
|
+
* flushed rows leave the live frame. Falls back to a raw stdout write when
|
|
74
|
+
* the patched API is unavailable.
|
|
75
|
+
*/
|
|
76
|
+
enqueueHistoryWrite?: (data: string) => void;
|
|
77
|
+
/**
|
|
78
|
+
* Wired by `renderApp`. Enables/disables the patched Ink bottom-anchor pad
|
|
79
|
+
* creation. On while the agent runs (footer must not jump as the tool panel
|
|
80
|
+
* and status rows churn); off at idle so symmetric UI shrink (slash menu
|
|
81
|
+
* close, input collapse) lets the footer return up without leaving pads.
|
|
82
|
+
*/
|
|
83
|
+
setFrameAnchorActive?: (active: boolean) => void;
|
|
68
84
|
/**
|
|
69
85
|
* When true, the UI runs in the alternate-screen fullscreen viewport: the
|
|
70
86
|
* transcript is rendered inside Ink as a bounded, app-scrolled region above a
|
package/dist/ui/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAqBA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAcrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAwBjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAkB,eAAe,EAAe,MAAM,6BAA6B,CAAC;AAEhG,OAAO,EAOL,KAAK,QAAQ,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/App.js
CHANGED
|
@@ -37,7 +37,7 @@ import { detectVerifyCommands } from "../core/verify-commands.js";
|
|
|
37
37
|
import { RewindOverlay } from "./components/RewindOverlay.js";
|
|
38
38
|
import { extractPlanSteps, findCompletedMarkers, markStepsCompleted, rebasePlanSteps, segmentDisplayText, stripDoneMarkers, } from "../utils/plan-steps.js";
|
|
39
39
|
import { getAllMcpServers } from "../core/mcp/index.js";
|
|
40
|
-
import { trimFlushedItems, flushOnTurnText, flushOnTurnEnd, flushOverflow, } from "./live-item-flush.js";
|
|
40
|
+
import { trimFlushedItems, flushOnTurnText, flushOnTurnEnd, flushOverflow, countOversizedFlushItems, } from "./live-item-flush.js";
|
|
41
41
|
import { splitAssistantStreamingText, estimateRenderedRows, } from "./utils/assistant-stream-split.js";
|
|
42
42
|
import { getNextPendingTask, markTaskInProgress } from "../core/tasks-store.js";
|
|
43
43
|
import { buildUserContentWithAttachments } from "./prompt-routing.js";
|
|
@@ -97,6 +97,11 @@ export function App(props) {
|
|
|
97
97
|
const switchTheme = useSetTheme();
|
|
98
98
|
const { write: writeStdout } = useStdout();
|
|
99
99
|
const { columns, rows } = useTerminalSize();
|
|
100
|
+
// Layout snapshot readable from agent-event callbacks (whose deps must stay
|
|
101
|
+
// stable). `liveAreaRows` is filled in by an effect after the chat layout is
|
|
102
|
+
// measured further down; 0 means "not measured yet" and disables the
|
|
103
|
+
// oversized-item flush below.
|
|
104
|
+
const liveLayoutRef = useRef({ columns, liveAreaRows: 0 });
|
|
100
105
|
// Hoisted before terminal title hook so it can reference them
|
|
101
106
|
const [lastUserMessage, setLastUserMessage] = useState("");
|
|
102
107
|
// Bumped on every prompt submit; the fullscreen transcript scroll controller
|
|
@@ -269,6 +274,9 @@ export function App(props) {
|
|
|
269
274
|
// accumulating in React state (still flushed + persisted) without any
|
|
270
275
|
// stdout writes. The legacy scrollback path keeps the printer.
|
|
271
276
|
terminalHistoryPrinter: props.fullscreen ? undefined : props.terminalHistoryPrinter,
|
|
277
|
+
// Atomic scrollback enqueue — only meaningful on the legacy scrollback
|
|
278
|
+
// path (fullscreen drops the printer entirely, so nothing is written).
|
|
279
|
+
enqueueStdout: props.fullscreen ? undefined : props.enqueueHistoryWrite,
|
|
272
280
|
terminalHistoryContext: {
|
|
273
281
|
theme,
|
|
274
282
|
columns,
|
|
@@ -791,8 +799,23 @@ export function App(props) {
|
|
|
791
799
|
const flushablePrev = prev.filter((item) => item.kind !== "assistant");
|
|
792
800
|
if (flushablePrev.length > 0)
|
|
793
801
|
queueFlush(flushablePrev);
|
|
802
|
+
// Finalized items taller than the live area can't stay pinned:
|
|
803
|
+
// streaming-time clamping no longer applies, so Ink would only
|
|
804
|
+
// paint the frame's bottom rows and the top of the response (e.g.
|
|
805
|
+
// a table header) would be invisible until the next turn's flush.
|
|
806
|
+
// The check is cumulative over the WHOLE pinned set (previously
|
|
807
|
+
// pinned assistant items + this turn's, which [DONE:N]
|
|
808
|
+
// segmentation can split into several): flush the leading prefix
|
|
809
|
+
// so the remaining suffix fits, preserving transcript order. The
|
|
810
|
+
// transcript-history layout effect removes the flushed ids from
|
|
811
|
+
// the live frame after printing.
|
|
812
|
+
const pinned = [...assistantItems, ...nextItems];
|
|
813
|
+
const layout = liveLayoutRef.current;
|
|
814
|
+
const oversizedCount = countOversizedFlushItems(pinned, (itemText) => estimateRenderedRows(itemText, layout.columns), layout.liveAreaRows);
|
|
815
|
+
if (oversizedCount > 0)
|
|
816
|
+
queueFlush(pinned.slice(0, oversizedCount));
|
|
794
817
|
streamedAssistantFlushRef.current = { flushedChars: 0, text: "" };
|
|
795
|
-
return
|
|
818
|
+
return pinned;
|
|
796
819
|
});
|
|
797
820
|
}, [queueFlush]),
|
|
798
821
|
onToolStart: useCallback((toolCallId, name, args, stream) => {
|
|
@@ -1439,6 +1462,22 @@ export function App(props) {
|
|
|
1439
1462
|
return () => clearTimeout(timer);
|
|
1440
1463
|
}
|
|
1441
1464
|
}, [agentLoop.isRunning, sessionStore, props.resetUI]);
|
|
1465
|
+
// Bottom-anchor gating: pad creation on while the agent runs, off at idle.
|
|
1466
|
+
// The idle transition is delayed 500ms so the finalization commits (done
|
|
1467
|
+
// status swap, live-item clear, deferred flushes) all land while the anchor
|
|
1468
|
+
// still protects them; only then does idle UI (slash menu open/close, input
|
|
1469
|
+
// grow/shrink) regain natural symmetric footer movement.
|
|
1470
|
+
const setFrameAnchorActive = props.setFrameAnchorActive;
|
|
1471
|
+
useEffect(() => {
|
|
1472
|
+
if (!setFrameAnchorActive)
|
|
1473
|
+
return;
|
|
1474
|
+
if (agentLoop.isRunning) {
|
|
1475
|
+
setFrameAnchorActive(true);
|
|
1476
|
+
return;
|
|
1477
|
+
}
|
|
1478
|
+
const timer = setTimeout(() => setFrameAnchorActive(false), 500);
|
|
1479
|
+
return () => clearTimeout(timer);
|
|
1480
|
+
}, [agentLoop.isRunning, setFrameAnchorActive]);
|
|
1442
1481
|
const showSessionSummaryAndExit = useCallback(() => {
|
|
1443
1482
|
const summary = buildSessionSummary({
|
|
1444
1483
|
stats: sessionStatsRef.current,
|
|
@@ -2166,17 +2205,19 @@ export function App(props) {
|
|
|
2166
2205
|
taskBarExpanded,
|
|
2167
2206
|
liveToolFeedCount: liveToolFeed.length,
|
|
2168
2207
|
});
|
|
2208
|
+
useEffect(() => {
|
|
2209
|
+
liveLayoutRef.current = { columns, liveAreaRows: measuredLiveAreaRows };
|
|
2210
|
+
}, [columns, measuredLiveAreaRows]);
|
|
2169
2211
|
const isPixelView = overlay === "pixel";
|
|
2170
2212
|
const hasLiveAssistantItem = liveItems.some((item) => item.kind === "assistant");
|
|
2171
2213
|
const rawVisibleStreamingText = hasLiveAssistantItem ? "" : agentLoop.streamingText;
|
|
2172
|
-
//
|
|
2173
|
-
//
|
|
2174
|
-
//
|
|
2175
|
-
//
|
|
2176
|
-
//
|
|
2177
|
-
//
|
|
2178
|
-
//
|
|
2179
|
-
// frame height monotonic, so the footer never bounces.
|
|
2214
|
+
// The live text is sliced by the COMMITTED `flushedChars` only. When the
|
|
2215
|
+
// flush effect below queues a paragraph, queueFlush enqueues the rendered
|
|
2216
|
+
// bytes through the patched Ink `insertBeforeFrame` (passive — no terminal
|
|
2217
|
+
// write) and the generation bump re-renders with the advanced flushedChars;
|
|
2218
|
+
// that commit's single frame write is `erase tall frame + paragraph bytes +
|
|
2219
|
+
// shorter frame`, so no frame ever shows the paragraph in both scrollback
|
|
2220
|
+
// and the live region, and the footer never bounces.
|
|
2180
2221
|
const alreadyFlushedChars = streamedAssistantFlushRef.current.flushedChars;
|
|
2181
2222
|
// Retry-safety gate: don't commit streamed paragraphs to permanent scrollback
|
|
2182
2223
|
// while the text is still small enough to live entirely in the live region.
|
|
@@ -2194,10 +2235,6 @@ export function App(props) {
|
|
|
2194
2235
|
? estimateRenderedRows(rawVisibleStreamingText.slice(alreadyFlushedChars), columns)
|
|
2195
2236
|
: 0;
|
|
2196
2237
|
const shouldFlushStreamedText = alreadyFlushedChars > 0 || unflushedStreamingRows > measuredLiveAreaRows;
|
|
2197
|
-
const pendingFlushChars = rawVisibleStreamingText && shouldFlushStreamedText
|
|
2198
|
-
? splitAssistantStreamingText(rawVisibleStreamingText.slice(alreadyFlushedChars)).flushedText
|
|
2199
|
-
.length
|
|
2200
|
-
: 0;
|
|
2201
2238
|
useEffect(() => {
|
|
2202
2239
|
if (!rawVisibleStreamingText) {
|
|
2203
2240
|
streamedAssistantFlushRef.current = { flushedChars: 0, text: "" };
|
|
@@ -2235,7 +2272,7 @@ export function App(props) {
|
|
|
2235
2272
|
text: rawVisibleStreamingText,
|
|
2236
2273
|
};
|
|
2237
2274
|
}, [rawVisibleStreamingText, shouldFlushStreamedText, queueFlush]);
|
|
2238
|
-
const visibleStreamingText = stripDoneMarkers(rawVisibleStreamingText.slice(alreadyFlushedChars
|
|
2275
|
+
const visibleStreamingText = stripDoneMarkers(rawVisibleStreamingText.slice(alreadyFlushedChars));
|
|
2239
2276
|
const lastLiveItem = liveItems.at(-1);
|
|
2240
2277
|
// For spacing decisions, the previous row is the last item that actually
|
|
2241
2278
|
// RENDERS. Panel-replaced tool items (now shown only in the LiveToolPanel)
|
|
@@ -2268,7 +2305,7 @@ export function App(props) {
|
|
|
2268
2305
|
// When earlier paragraphs of THIS response were already flushed to scrollback
|
|
2269
2306
|
// mid-stream, the live remainder is the next paragraph — re-insert the blank
|
|
2270
2307
|
// line that separated them so the live tail lines up with the flushed history.
|
|
2271
|
-
const streamingContinuesFlushed = alreadyFlushedChars
|
|
2308
|
+
const streamingContinuesFlushed = alreadyFlushedChars > 0;
|
|
2272
2309
|
// ── Fullscreen alt-screen transcript ───────────────────
|
|
2273
2310
|
// Flatten history + live items + in-flight streaming into the flat ANSI line
|
|
2274
2311
|
// buffer the viewport renders. Reuses the same serializer the legacy
|