@@ -180,6 +180,57 @@ function ToolDiffHarness(): React.ReactElement {
180180 } ) ;
181181}
182182
183+ function ToolGroupFlushHarness ( ) : React . ReactElement {
184+ const bus = useMemo ( ( ) => new EventBus ( ) , [ ] ) ;
185+ const { transcriptNodes, startTurn, completeTurn, nextId } = useAgentLog ( {
186+ bus,
187+ model : "test-model" ,
188+ } ) ;
189+
190+ useEffect ( ( ) => {
191+ startTurn ( nextId ( "turn" ) , "Check LSP" , Date . now ( ) ) ;
192+ bus . emit ( "tool:before" , {
193+ name : "lsp" ,
194+ params : { operation : "diagnostics" , path : "src/tmp-lsp-validation.ts" } ,
195+ callId : "call-1" ,
196+ } ) ;
197+ bus . emit ( "tool:before" , {
198+ name : "lsp" ,
199+ params : { operation : "symbols" , path : "src/tmp-lsp-validation.ts" } ,
200+ callId : "call-2" ,
201+ } ) ;
202+ bus . emit ( "tool:after" , {
203+ name : "lsp" ,
204+ callId : "call-1" ,
205+ durationMs : 1 ,
206+ result : {
207+ success : true ,
208+ output : "No diagnostics." ,
209+ error : null ,
210+ artifacts : [ ] ,
211+ } ,
212+ } ) ;
213+ bus . emit ( "tool:after" , {
214+ name : "lsp" ,
215+ callId : "call-2" ,
216+ durationMs : 9 ,
217+ result : {
218+ success : true ,
219+ output : "1 symbol." ,
220+ error : null ,
221+ artifacts : [ ] ,
222+ } ,
223+ } ) ;
224+ completeTurn ( nextId ( "summary" ) , makeTurnSummaryPart ( { iterations : 1 , toolCalls : 2 , cost : 0 , elapsedMs : 10 } ) ) ;
225+ } , [ bus , startTurn , completeTurn , nextId ] ) ;
226+
227+ return React . createElement ( TranscriptView , {
228+ showWelcome : false ,
229+ transcriptNodes,
230+ model : "test-model" ,
231+ } ) ;
232+ }
233+
183234function StatusHarness ( ) : React . ReactElement {
184235 const bus = useMemo ( ( ) => new EventBus ( ) , [ ] ) ;
185236 const { transcriptNodes, startTurn, completeTurn, nextId } = useAgentLog ( {
@@ -701,6 +752,17 @@ describe("interactive completion notices", () => {
701752 expect ( output ) . not . toContain ( "+++ b/src/new-file.ts" ) ;
702753 expect ( output ) . toContain ( "... +2 more files" ) ;
703754 } ) ;
755+
756+ it ( "flushes grouped tool rows as soon as all calls complete" , async ( ) => {
757+ const view = renderForTest ( React . createElement ( ToolGroupFlushHarness ) ) ;
758+
759+ await settle ( ) ;
760+
761+ const plain = stripAnsi ( view . stdout . readAll ( ) ) ;
762+ expect ( plain ) . toContain ( "Check LSP" ) ;
763+ expect ( plain ) . toContain ( "✓ lsp ×2" ) ;
764+ expect ( plain ) . toContain ( "tmp-lsp-validation.ts, tmp-lsp-validation.ts" ) ;
765+ } ) ;
704766} ) ;
705767
706768describe ( "framed TUI wrapping" , ( ) => {
0 commit comments