@@ -2788,22 +2788,24 @@ describe("CodexAppServerEventProjector", () => {
27882788 terminalPresentation = observation . terminalPresentation ;
27892789 } ,
27902790 } ) ;
2791+ const item = {
2792+ type : "commandExecution" ,
2793+ id : "command-clear-presentation" ,
2794+ command : "git status --short" ,
2795+ cwd : "/workspace" ,
2796+ processId : null ,
2797+ source : "agent" ,
2798+ status : "completed" ,
2799+ commandActions : [ { type : "unknown" , command : "git status --short" } ] ,
2800+ aggregatedOutput : "" ,
2801+ exitCode : 0 ,
2802+ durationMs : 1 ,
2803+ } ;
27912804
2805+ await projector . handleNotification ( forCurrentTurn ( "item/started" , { item } ) ) ;
27922806 await projector . handleNotification (
27932807 forCurrentTurn ( "item/completed" , {
2794- item : {
2795- type : "commandExecution" ,
2796- id : "command-clear-presentation" ,
2797- command : "git status --short" ,
2798- cwd : "/workspace" ,
2799- processId : null ,
2800- source : "agent" ,
2801- status : "completed" ,
2802- commandActions : [ { type : "unknown" , command : "git status --short" } ] ,
2803- aggregatedOutput : "" ,
2804- exitCode : 0 ,
2805- durationMs : 1 ,
2806- } ,
2808+ item,
28072809 } ) ,
28082810 ) ;
28092811
@@ -2826,9 +2828,90 @@ describe("CodexAppServerEventProjector", () => {
28262828 id : "image-view-clear-presentation" ,
28272829 path : "/workspace/reference.png" ,
28282830 } ,
2831+ {
2832+ type : "dynamicToolCall" ,
2833+ id : "stale-dynamic-tool" ,
2834+ turnId : "turn-old" ,
2835+ tool : "web_fetch" ,
2836+ status : "completed" ,
2837+ } ,
2838+ ] ) ,
2839+ ) ;
2840+
2841+ expect ( terminalPresentation ) . toBeUndefined ( ) ;
2842+ } ) ;
2843+
2844+ it ( "keeps a later dynamic presentation over an earlier snapshot-only native tool" , async ( ) => {
2845+ let terminalPresentation : string | undefined = "later dynamic result" ;
2846+ let latestOrdinal = 1 ;
2847+ let nextOrdinal = 0 ;
2848+ const projector = await createProjector ( {
2849+ ...( await createParams ( ) ) ,
2850+ allocateToolOutcomeOrdinal : ( ) => nextOrdinal ++ ,
2851+ onToolOutcome : ( observation ) => {
2852+ const ordinal = observation . toolCallOrdinal ?? latestOrdinal + 1 ;
2853+ if ( ordinal >= latestOrdinal ) {
2854+ latestOrdinal = ordinal ;
2855+ terminalPresentation = observation . terminalPresentation ;
2856+ }
2857+ } ,
2858+ } ) ;
2859+ const nativeItem = {
2860+ type : "imageView" ,
2861+ id : "image-view-before-dynamic" ,
2862+ path : "/workspace/reference.png" ,
2863+ } ;
2864+
2865+ await projector . handleNotification (
2866+ forCurrentTurn ( "item/completed" , {
2867+ item : nativeItem ,
2868+ } ) ,
2869+ ) ;
2870+
2871+ await projector . handleNotification (
2872+ turnCompleted ( [
2873+ nativeItem ,
2874+ {
2875+ type : "dynamicToolCall" ,
2876+ id : "dynamic-after-image-view" ,
2877+ turnId : TURN_ID ,
2878+ tool : "web_fetch" ,
2879+ status : "completed" ,
2880+ } ,
2881+ {
2882+ type : "imageView" ,
2883+ id : "stale-image-view" ,
2884+ turnId : "turn-old" ,
2885+ path : "/workspace/stale.png" ,
2886+ } ,
28292887 ] ) ,
28302888 ) ;
28312889
2890+ expect ( terminalPresentation ) . toBe ( "later dynamic result" ) ;
2891+ } ) ;
2892+
2893+ it ( "clears a prior presentation for a completion-only native item without a turn snapshot" , async ( ) => {
2894+ let terminalPresentation : string | undefined = "stale dynamic result" ;
2895+ let nextOrdinal = 1 ;
2896+ const projector = await createProjector ( {
2897+ ...( await createParams ( ) ) ,
2898+ allocateToolOutcomeOrdinal : ( ) => nextOrdinal ++ ,
2899+ onToolOutcome : ( observation ) => {
2900+ terminalPresentation = observation . terminalPresentation ;
2901+ } ,
2902+ } ) ;
2903+
2904+ await projector . handleNotification (
2905+ forCurrentTurn ( "item/completed" , {
2906+ item : {
2907+ type : "imageView" ,
2908+ id : "completion-only-image-view" ,
2909+ path : "/workspace/reference.png" ,
2910+ } ,
2911+ } ) ,
2912+ ) ;
2913+ await projector . handleNotification ( turnCompleted ( [ ] ) ) ;
2914+
28322915 expect ( terminalPresentation ) . toBeUndefined ( ) ;
28332916 } ) ;
28342917
0 commit comments