@@ -20,6 +20,7 @@ import { createInterface } from 'node:readline';
2020import { toArray } from '@antfu/utils' ;
2121import { Result } from '@praha/byethrow' ;
2222import { uniq } from 'es-toolkit' ;
23+ import { sort } from 'fast-sort' ;
2324import { createFixture } from 'fs-fixture' ;
2425import { isDirectorySync } from 'path-type' ;
2526import { glob } from 'tinyglobby' ;
@@ -901,7 +902,7 @@ export async function loadDailyUsageData(options?: LoadOptions): Promise<DailyUs
901902 * Loads and aggregates Claude usage data by session
902903 * Groups usage data by project path and session ID based on file structure
903904 * @param options - Optional configuration for loading and filtering data
904- * @returns Array of session usage summaries sorted by last activity
905+ * @returns Array of session usage summaries sorted by cost (highest first)
905906 */
906907export async function loadSessionData ( options ?: LoadOptions ) : Promise < SessionUsage [ ] > {
907908 // Get all Claude paths or use the specific one from options
@@ -1072,7 +1073,17 @@ export async function loadSessionData(options?: LoadOptions): Promise<SessionUsa
10721073 options ?. project ,
10731074 ) ;
10741075
1075- return sortByDate ( sessionFiltered , ( item ) => item . lastActivity , options ?. order ) ;
1076+ // Sort sessions by cost (highest first by default), as documented
1077+ const sorted = sort ( sessionFiltered ) ;
1078+ const order = options ?. order ?? 'desc' ;
1079+ switch ( order ) {
1080+ case 'asc' :
1081+ return sorted . asc ( ( item ) => item . totalCost ) ;
1082+ case 'desc' :
1083+ return sorted . desc ( ( item ) => item . totalCost ) ;
1084+ default :
1085+ unreachable ( order ) ;
1086+ }
10761087}
10771088
10781089/**
@@ -2801,14 +2812,14 @@ invalid json line
28012812 expect ( session ?. versions ) . toEqual ( [ '1.0.0' , '1.1.0' ] ) ; // Sorted and unique
28022813 } ) ;
28032814
2804- it ( 'sorts by last activity descending' , async ( ) => {
2815+ it ( 'sorts by cost descending by default ' , async ( ) => {
28052816 const sessions = [
28062817 {
28072818 sessionId : 'session1' ,
28082819 data : {
28092820 timestamp : createISOTimestamp ( '2024-01-15T12:00:00Z' ) ,
28102821 message : { usage : { input_tokens : 100 , output_tokens : 50 } } ,
2811- costUSD : 0.01 ,
2822+ costUSD : 0.05 ,
28122823 } ,
28132824 } ,
28142825 {
@@ -2824,7 +2835,7 @@ invalid json line
28242835 data : {
28252836 timestamp : createISOTimestamp ( '2024-01-31T12:00:00Z' ) ,
28262837 message : { usage : { input_tokens : 100 , output_tokens : 50 } } ,
2827- costUSD : 0.01 ,
2838+ costUSD : 0.1 ,
28282839 } ,
28292840 } ,
28302841 ] ;
@@ -2837,21 +2848,21 @@ invalid json line
28372848 } ,
28382849 } ) ;
28392850
2840- const result = await loadSessionData ( { claudePath : fixture . path } ) ;
2851+ const result = await loadSessionData ( { claudePath : fixture . path , mode : 'display' } ) ;
28412852
2842- expect ( result [ 0 ] ?. sessionId ) . toBe ( 'session3' ) ;
2853+ expect ( result [ 0 ] ?. sessionId ) . toBe ( 'session3' ) ; // highest cost
28432854 expect ( result [ 1 ] ?. sessionId ) . toBe ( 'session1' ) ;
2844- expect ( result [ 2 ] ?. sessionId ) . toBe ( 'session2' ) ;
2855+ expect ( result [ 2 ] ?. sessionId ) . toBe ( 'session2' ) ; // lowest cost
28452856 } ) ;
28462857
2847- it ( "sorts by last activity ascending when order is 'asc'" , async ( ) => {
2858+ it ( "sorts by cost ascending when order is 'asc'" , async ( ) => {
28482859 const sessions = [
28492860 {
28502861 sessionId : 'session1' ,
28512862 data : {
28522863 timestamp : createISOTimestamp ( '2024-01-15T12:00:00Z' ) ,
28532864 message : { usage : { input_tokens : 100 , output_tokens : 50 } } ,
2854- costUSD : 0.01 ,
2865+ costUSD : 0.05 ,
28552866 } ,
28562867 } ,
28572868 {
@@ -2867,7 +2878,7 @@ invalid json line
28672878 data : {
28682879 timestamp : createISOTimestamp ( '2024-01-31T12:00:00Z' ) ,
28692880 message : { usage : { input_tokens : 100 , output_tokens : 50 } } ,
2870- costUSD : 0.01 ,
2881+ costUSD : 0.1 ,
28712882 } ,
28722883 } ,
28732884 ] ;
@@ -2883,21 +2894,22 @@ invalid json line
28832894 const result = await loadSessionData ( {
28842895 claudePath : fixture . path ,
28852896 order : 'asc' ,
2897+ mode : 'display' ,
28862898 } ) ;
28872899
2888- expect ( result [ 0 ] ?. sessionId ) . toBe ( 'session2' ) ; // oldest first
2900+ expect ( result [ 0 ] ?. sessionId ) . toBe ( 'session2' ) ; // lowest cost first
28892901 expect ( result [ 1 ] ?. sessionId ) . toBe ( 'session1' ) ;
2890- expect ( result [ 2 ] ?. sessionId ) . toBe ( 'session3' ) ; // newest last
2902+ expect ( result [ 2 ] ?. sessionId ) . toBe ( 'session3' ) ; // highest cost last
28912903 } ) ;
28922904
2893- it ( "sorts by last activity descending when order is 'desc'" , async ( ) => {
2905+ it ( "sorts by cost descending when order is 'desc'" , async ( ) => {
28942906 const sessions = [
28952907 {
28962908 sessionId : 'session1' ,
28972909 data : {
28982910 timestamp : createISOTimestamp ( '2024-01-15T12:00:00Z' ) ,
28992911 message : { usage : { input_tokens : 100 , output_tokens : 50 } } ,
2900- costUSD : 0.01 ,
2912+ costUSD : 0.05 ,
29012913 } ,
29022914 } ,
29032915 {
@@ -2913,7 +2925,7 @@ invalid json line
29132925 data : {
29142926 timestamp : createISOTimestamp ( '2024-01-31T12:00:00Z' ) ,
29152927 message : { usage : { input_tokens : 100 , output_tokens : 50 } } ,
2916- costUSD : 0.01 ,
2928+ costUSD : 0.1 ,
29172929 } ,
29182930 } ,
29192931 ] ;
@@ -2929,11 +2941,12 @@ invalid json line
29292941 const result = await loadSessionData ( {
29302942 claudePath : fixture . path ,
29312943 order : 'desc' ,
2944+ mode : 'display' ,
29322945 } ) ;
29332946
2934- expect ( result [ 0 ] ?. sessionId ) . toBe ( 'session3' ) ; // newest first (same as default)
2947+ expect ( result [ 0 ] ?. sessionId ) . toBe ( 'session3' ) ; // highest cost (same as default)
29352948 expect ( result [ 1 ] ?. sessionId ) . toBe ( 'session1' ) ;
2936- expect ( result [ 2 ] ?. sessionId ) . toBe ( 'session2' ) ; // oldest last
2949+ expect ( result [ 2 ] ?. sessionId ) . toBe ( 'session2' ) ; // lowest cost
29372950 } ) ;
29382951
29392952 it ( 'filters by date range based on last activity' , async ( ) => {
0 commit comments