@@ -83,15 +83,6 @@ func (c *Calculator) CalculateAPI(storage core.Storage, opts APIOptions) (*APISt
8383 lifetimeHours [lr .Language ] = lr .TotalTime / 3600
8484 }
8585
86- projectLangs := make (map [string ]map [string ]float64 )
87- for _ , pr := range allTimeProjs {
88- pl := make (map [string ]float64 )
89- for _ , lr := range allTimeLangs {
90- pl [lr .Language ] = lr .TotalTime / 3600
91- }
92- projectLangs [pr .Project ] = pl
93- }
94-
9586 cutoff := time .Now ().AddDate (0 , 0 , - opts .LoadRecentDays )
9687 activities , err := storage .GetActivitiesSince (cutoff )
9788 if err != nil {
@@ -104,6 +95,15 @@ func (c *Calculator) CalculateAPI(storage core.Storage, opts APIOptions) (*APISt
10495 activities , sessions := sessionMgr .GroupAndCalculate (activities )
10596 sessionsByDay := c .indexSessionsByDay (sessions )
10697
98+ // Build projectLangs map using durations from grouped activities
99+ projectLangs := make (map [string ]map [string ]float64 )
100+ for _ , a := range activities {
101+ if projectLangs [a .Project ] == nil {
102+ projectLangs [a .Project ] = make (map [string ]float64 )
103+ }
104+ projectLangs [a.Project ][a.Language ] += a .Duration
105+ }
106+
107107 today := c .buildPeriodFromSummary ("today" , todaySummary , todayLangs , todayProjs , todayEditors , sessions , sessionsByDay , lifetimeHours , projectLangs , todayStart , now , activities )
108108 yesterday := c .buildPeriodFromSummary ("yesterday" , yesterdaySummary , yesterdayLangs , yesterdayProjs , yesterdayEditors , sessions , sessionsByDay , lifetimeHours , projectLangs , yesterdayStart , todayStart , activities )
109109 thisWeek := c .buildPeriodFromSummary ("this_week" , thisWeekSummary , thisWeekLangs , thisWeekProjs , thisWeekEditors , sessions , sessionsByDay , lifetimeHours , projectLangs , thisWeekStart , now , activities )
@@ -310,22 +310,62 @@ func (c *Calculator) convertLanguageRows(rows []core.LanguageRow, lifetimeHours
310310func (c * Calculator ) convertProjectRows (rows []core.ProjectRow , projectLangs map [string ]map [string ]float64 , total float64 ) []APIProjectStats {
311311 result := make ([]APIProjectStats , 0 , len (rows ))
312312 for _ , r := range rows {
313- mainLang := r .MainLanguage
313+ mainLang := ""
314+
315+ if langs , ok := projectLangs [r .Project ]; ok {
316+ // Priority 1: Most used actual programming language (CODE)
317+ maxDur := - 1.0
318+ for lang , dur := range langs {
319+ if IsCodeLanguage (lang ) && dur > maxDur {
320+ maxDur = dur
321+ mainLang = lang
322+ }
323+ }
324+
325+ // Priority 2: Most used Documentation or Markup (Useful for notes/web)
326+ if mainLang == "" {
327+ maxDur = - 1.0
328+ for lang , dur := range langs {
329+ class := GetLanguageClass (lang )
330+ if (class == "doc" || class == "markup" ) && IsValidLanguage (lang ) && dur > maxDur {
331+ maxDur = dur
332+ mainLang = lang
333+ }
334+ }
335+ }
314336
315- // If mainLang is not a code language, find the first code language from projectLangs
316- if mainLang == "" || ! IsCodeLanguage (mainLang ) {
317- if langs , ok := projectLangs [r .Project ]; ok {
318- for lang := range langs {
319- if IsCodeLanguage (lang ) {
337+ // Priority 3: Most used Data or Config
338+ if mainLang == "" {
339+ maxDur = - 1.0
340+ for lang , dur := range langs {
341+ class := GetLanguageClass (lang )
342+ if (class == "data" || class == "config" ) && IsValidLanguage (lang ) && dur > maxDur {
343+ maxDur = dur
320344 mainLang = lang
321- break
322345 }
323346 }
324347 }
348+
349+ // Priority 4: Any other non-meta valid language
350+ if mainLang == "" {
351+ maxDur = - 1.0
352+ for lang , dur := range langs {
353+ if IsValidLanguage (lang ) && dur > maxDur {
354+ maxDur = dur
355+ mainLang = lang
356+ }
357+ }
358+ }
359+ }
360+
361+ // Fallback to the row's main language only if it's actually valid
362+ if mainLang == "" && IsValidLanguage (r .MainLanguage ) {
363+ mainLang = r .MainLanguage
325364 }
326365
327- if mainLang == "" || ! IsCodeLanguage (mainLang ) {
328- mainLang = "Mixed"
366+ // Final safety fallback
367+ if mainLang == "" {
368+ mainLang = "Project"
329369 }
330370
331371 pct := 0.0
0 commit comments