@@ -874,6 +874,50 @@ describe("chat goal status", () => {
874874 } ) ;
875875} ) ;
876876
877+ describe ( "chat token usage meter" , ( ) => {
878+ it ( "renders the active session context usage, including a valid zero-token session" , ( ) => {
879+ const container = renderChatView ( {
880+ sessions : createSessionsResultFromRows ( [
881+ {
882+ key : "main" ,
883+ kind : "direct" ,
884+ updatedAt : 2 ,
885+ totalTokens : 0 ,
886+ contextTokens : 200_000 ,
887+ } ,
888+ ] ) ,
889+ } ) ;
890+
891+ const meter = requireElement ( container , ".token-meter" , "token usage meter" ) ;
892+ expect ( meter . getAttribute ( "role" ) ) . toBe ( "progressbar" ) ;
893+ expect ( meter . getAttribute ( "aria-valuenow" ) ) . toBe ( "0" ) ;
894+ expect ( meter . closest ( ".agent-chat__input" ) ) . not . toBeNull ( ) ;
895+ expect ( meter . closest ( ".agent-chat__toolbar" ) ) . toBeNull ( ) ;
896+ expect ( container . querySelector < HTMLElement > ( ".token-meter__bar" ) ?. style . width ) . toBe ( "0%" ) ;
897+ } ) ;
898+
899+ it ( "uses the session context window before the default context window" , ( ) => {
900+ const container = renderChatView ( {
901+ sessions : {
902+ ...createSessionsResultFromRows ( [
903+ {
904+ key : "main" ,
905+ kind : "direct" ,
906+ updatedAt : 2 ,
907+ totalTokens : 90_000 ,
908+ contextTokens : 100_000 ,
909+ } ,
910+ ] ) ,
911+ defaults : { modelProvider : "openai" , model : "gpt-5" , contextTokens : 200_000 } ,
912+ } ,
913+ } ) ;
914+
915+ const meter = requireElement ( container , ".token-meter" , "token usage meter" ) ;
916+ expect ( meter . getAttribute ( "aria-valuenow" ) ) . toBe ( "90" ) ;
917+ expect ( container . querySelector ( ".token-meter__bar--high" ) ) . not . toBeNull ( ) ;
918+ } ) ;
919+ } ) ;
920+
877921describe ( "chat composer workbench" , ( ) => {
878922 it ( "renders session controls in the composer and workspace files in the rail" , ( ) => {
879923 const onRefresh = vi . fn ( ) ;
0 commit comments