@@ -135,15 +135,26 @@ func (m *sidebarCmp) View() string {
135135 parts = append(parts,
136136 m.currentModelBlock(),
137137 )
138− if m.session.ID != "" {
139− parts = append(parts, "", m.filesBlock())
138+
139+ // Check if we should use horizontal layout for sections
140+ if m.compactMode && m.width > m.height {
141+ // Horizontal layout for compact mode when width > height
142+ sectionsContent := m.renderSectionsHorizontal()
143+ if sectionsContent != "" {
144+ parts = append(parts, "", sectionsContent)
145+ }
146+ } else {
147+ // Vertical layout (default)
148+ if m.session.ID != "" {
149+ parts = append(parts, "", m.filesBlock())
150+ }
151+ parts = append(parts,
152+ "",
153+ m.lspBlock(),
154+ "",
155+ m.mcpBlock(),
156+ )
140157 }
141− parts = append(parts,
142− "",
143− m.lspBlock(),
144− "",
145− m.mcpBlock(),
146− )
147158
148159 style := t.S().Base.
149160 Width(m.width).
@@ -347,6 +358,255 @@ func (m *sidebarCmp) getDynamicLimits() (maxFiles, maxLSPs, maxMCPs int) {
347358 return maxFiles, maxLSPs, maxMCPs
348359}
349360
361+// renderSectionsHorizontal renders the files, LSPs, and MCPs sections horizontally
362+func (m *sidebarCmp) renderSectionsHorizontal() string {
363+ // Calculate available width for each section
364+ totalWidth := m.width - 4 // Account for padding and spacing
365+ sectionWidth := min(50, totalWidth/3)
366+
367+ // Get the sections content with limited height
368+ var filesContent, lspContent, mcpContent string
369+
370+ filesContent = m.filesBlockCompact(sectionWidth)
371+ lspContent = m.lspBlockCompact(sectionWidth)
372+ mcpContent = m.mcpBlockCompact(sectionWidth)
373+
374+ return lipgloss.JoinHorizontal(lipgloss.Top, filesContent, " ", lspContent, " ", mcpContent)
375+}
376+
377+// filesBlockCompact renders the files block with limited width and height for horizontal layout
378+func (m *sidebarCmp) filesBlockCompact(maxWidth int) string {
379+ t := styles.CurrentTheme()
380+
381+ section := t.S().Subtle.Render("Modified Files")
382+
383+ files := make([]SessionFile, 0)
384+ m.files.Range(func(key, value any) bool {
385+ file := value.(SessionFile)
386+ files = append(files, file)
387+ return true
388+ })
389+
390+ if len(files) == 0 {
391+ content := lipgloss.JoinVertical(
392+ lipgloss.Left,
393+ section,
394+ "",
395+ t.S().Base.Foreground(t.Border).Render("None"),
396+ )
397+ return lipgloss.NewStyle().Width(maxWidth).Render(content)
398+ }
399+
400+ fileList := []string{section, ""}
401+ sort.Slice(files, func(i, j int) bool {
402+ return files[i].History.latestVersion.CreatedAt > files[j].History.latestVersion.CreatedAt
403+ })
404+
405+ // Limit items for horizontal layout - use less space
406+ maxItems := min(5, len(files))
407+ availableHeight := m.height - 8 // Reserve space for header and other content
408+ if availableHeight > 0 {
409+ maxItems = min(maxItems, availableHeight)
410+ }
411+
412+ filesShown := 0
413+ for _, file := range files {
414+ if file.Additions == 0 && file.Deletions == 0 {
415+ continue
416+ }
417+ if filesShown >= maxItems {
418+ break
419+ }
420+
421+ var statusParts []string
422+ if file.Additions > 0 {
423+ statusParts = append(statusParts, t.S().Base.Foreground(t.Success).Render(fmt.Sprintf("+%d", file.Additions)))
424+ }
425+ if file.Deletions > 0 {
426+ statusParts = append(statusParts, t.S().Base.Foreground(t.Error).Render(fmt.Sprintf("-%d", file.Deletions)))
427+ }
428+
429+ extraContent := strings.Join(statusParts, " ")
430+ cwd := config.Get().WorkingDir() + string(os.PathSeparator)
431+ filePath := file.FilePath
432+ filePath = strings.TrimPrefix(filePath, cwd)
433+ filePath = fsext.DirTrim(fsext.PrettyPath(filePath), 2)
434+ filePath = ansi.Truncate(filePath, maxWidth-lipgloss.Width(extraContent)-2, "…")
435+
436+ fileList = append(fileList,
437+ core.Status(
438+ core.StatusOpts{
439+ IconColor: t.FgMuted,
440+ NoIcon: true,
441+ Title: filePath,
442+ ExtraContent: extraContent,
443+ },
444+ maxWidth,
445+ ),
446+ )
447+ filesShown++
448+ }
449+
450+ // Add "..." indicator if there are more files
451+ totalFilesWithChanges := 0
452+ for _, file := range files {
453+ if file.Additions > 0 || file.Deletions > 0 {
454+ totalFilesWithChanges++
455+ }
456+ }
457+ if totalFilesWithChanges > maxItems {
458+ fileList = append(fileList, t.S().Base.Foreground(t.FgMuted).Render("…"))
459+ }
460+
461+ content := lipgloss.JoinVertical(lipgloss.Left, fileList...)
462+ return lipgloss.NewStyle().Width(maxWidth).Render(content)
463+}
464+
465+// lspBlockCompact renders the LSP block with limited width and height for horizontal layout
466+func (m *sidebarCmp) lspBlockCompact(maxWidth int) string {
467+ t := styles.CurrentTheme()
468+
469+ section := t.S().Subtle.Render("LSPs")
470+
471+ lspList := []string{section, ""}
472+
473+ lsp := config.Get().LSP.Sorted()
474+ if len(lsp) == 0 {
475+ content := lipgloss.JoinVertical(
476+ lipgloss.Left,
477+ section,
478+ "",
479+ t.S().Base.Foreground(t.Border).Render("None"),
480+ )
481+ return lipgloss.NewStyle().Width(maxWidth).Render(content)
482+ }
483+
484+ // Limit items for horizontal layout
485+ maxItems := min(5, len(lsp))
486+ availableHeight := m.height - 8
487+ if availableHeight > 0 {
488+ maxItems = min(maxItems, availableHeight)
489+ }
490+
491+ for i, l := range lsp {
492+ if i >= maxItems {
493+ break
494+ }
495+
496+ iconColor := t.Success
497+ if l.LSP.Disabled {
498+ iconColor = t.FgMuted
499+ }
500+
501+ lspErrs := map[protocol.DiagnosticSeverity]int{
502+ protocol.SeverityError: 0,
503+ protocol.SeverityWarning: 0,
504+ protocol.SeverityHint: 0,
505+ protocol.SeverityInformation: 0,
506+ }
507+ if client, ok := m.lspClients[l.Name]; ok {
508+ for _, diagnostics := range client.GetDiagnostics() {
509+ for _, diagnostic := range diagnostics {
510+ if severity, ok := lspErrs[diagnostic.Severity]; ok {
511+ lspErrs[diagnostic.Severity] = severity + 1
512+ }
513+ }
514+ }
515+ }
516+
517+ errs := []string{}
518+ if lspErrs[protocol.SeverityError] > 0 {
519+ errs = append(errs, t.S().Base.Foreground(t.Error).Render(fmt.Sprintf("%s %d", styles.ErrorIcon, lspErrs[protocol.SeverityError])))
520+ }
521+ if lspErrs[protocol.SeverityWarning] > 0 {
522+ errs = append(errs, t.S().Base.Foreground(t.Warning).Render(fmt.Sprintf("%s %d", styles.WarningIcon, lspErrs[protocol.SeverityWarning])))
523+ }
524+ if lspErrs[protocol.SeverityHint] > 0 {
525+ errs = append(errs, t.S().Base.Foreground(t.FgHalfMuted).Render(fmt.Sprintf("%s %d", styles.HintIcon, lspErrs[protocol.SeverityHint])))
526+ }
527+ if lspErrs[protocol.SeverityInformation] > 0 {
528+ errs = append(errs, t.S().Base.Foreground(t.FgHalfMuted).Render(fmt.Sprintf("%s %d", styles.InfoIcon, lspErrs[protocol.SeverityInformation])))
529+ }
530+
531+ lspList = append(lspList,
532+ core.Status(
533+ core.StatusOpts{
534+ IconColor: iconColor,
535+ Title: l.Name,
536+ Description: l.LSP.Command,
537+ ExtraContent: strings.Join(errs, " "),
538+ },
539+ maxWidth,
540+ ),
541+ )
542+ }
543+
544+ // Add "..." indicator if there are more LSPs
545+ if len(lsp) > maxItems {
546+ lspList = append(lspList, t.S().Base.Foreground(t.FgMuted).Render("…"))
547+ }
548+
549+ content := lipgloss.JoinVertical(lipgloss.Left, lspList...)
550+ return lipgloss.NewStyle().Width(maxWidth).Render(content)
551+}
552+
553+// mcpBlockCompact renders the MCP block with limited width and height for horizontal layout
554+func (m *sidebarCmp) mcpBlockCompact(maxWidth int) string {
555+ t := styles.CurrentTheme()
556+
557+ section := t.S().Subtle.Render("MCPs")
558+
559+ mcpList := []string{section, ""}
560+
561+ mcps := config.Get().MCP.Sorted()
562+ if len(mcps) == 0 {
563+ content := lipgloss.JoinVertical(
564+ lipgloss.Left,
565+ section,
566+ "",
567+ t.S().Base.Foreground(t.Border).Render("None"),
568+ )
569+ return lipgloss.NewStyle().Width(maxWidth).Render(content)
570+ }
571+
572+ // Limit items for horizontal layout
573+ maxItems := min(5, len(mcps))
574+ availableHeight := m.height - 8
575+ if availableHeight > 0 {
576+ maxItems = min(maxItems, availableHeight)
577+ }
578+
579+ for i, l := range mcps {
580+ if i >= maxItems {
581+ break
582+ }
583+
584+ iconColor := t.Success
585+ if l.MCP.Disabled {
586+ iconColor = t.FgMuted
587+ }
588+
589+ mcpList = append(mcpList,
590+ core.Status(
591+ core.StatusOpts{
592+ IconColor: iconColor,
593+ Title: l.Name,
594+ Description: l.MCP.Command,
595+ },
596+ maxWidth,
597+ ),
598+ )
599+ }
600+
601+ // Add "..." indicator if there are more MCPs
602+ if len(mcps) > maxItems {
603+ mcpList = append(mcpList, t.S().Base.Foreground(t.FgMuted).Render("…"))
604+ }
605+
606+ content := lipgloss.JoinVertical(lipgloss.Left, mcpList...)
607+ return lipgloss.NewStyle().Width(maxWidth).Render(content)
608+}
609+
350610func (m *sidebarCmp) filesBlock() string {
351611 t := styles.CurrentTheme()
352612