Skip to content

Conversation

@Aarekaz
Copy link
Collaborator

@Aarekaz Aarekaz commented Dec 11, 2025

This pull request introduces a new interactive TUI (Text User Interface) dashboard for managing and browsing local sessions, along with the necessary CLI command and supporting UI components. The dashboard provides a user-friendly way to view session statistics, browse sessions, filter/search, and navigate using keyboard shortcuts. The implementation includes new React components, hooks, and updates to documentation and dependencies.

Major additions and changes:

1. Interactive Dashboard Feature

  • Added a new CLI command sessionbase dashboard to launch an interactive dashboard for session management, including keyboard navigation and platform filtering. (README.md, src/commands/dashboard.ts, src/index.ts) [1] [2] [3] [4]

2. Dashboard UI Architecture

  • Implemented the main React app (App.tsx) for the dashboard, handling state, keyboard shortcuts, view switching (dashboard/sessions), search, filtering, and session detail navigation.
  • Added a MainContent component to switch between the dashboard view and sessions view based on user input.
  • Introduced a Sidebar and other supporting UI elements for navigation and context (not shown in the diff but referenced in App.tsx).

3. Session Browsing and Search

  • Created a SessionList component for listing sessions with platform icons, previews, and details, supporting navigation and paging.
  • Added a SearchBar component for searching/filtering sessions interactively.

4. Dashboard Statistics and Visualization

  • Implemented an ActivityHeatmap component to visualize session activity over the last 28 days, showing active days and intensity.
  • Added a reusable BorderedBox component for consistent UI framing.

5. Dependency and Documentation Updates

  • Updated package.json to include new dependencies required for the TUI (e.g., ink, react, date-fns, and related types).
  • Expanded the README.md with usage instructions, dashboard features, and keyboard shortcuts. [1] [2]

These changes collectively provide a robust, interactive way for users to manage and explore their sessions directly from the terminal.

- Introduced state management for detail expansion and pagination in the App component.
- Updated the SessionsView to conditionally render either a preview or a full transcript based on the detailExpanded state.
- Implemented a new function to handle the rendering of the full transcript with pagination support.
- Enhanced the useSessionDetail hook to include fullLines for detailed session data.
@Aarekaz Aarekaz marked this pull request as draft December 11, 2025 02:06
@Aarekaz Aarekaz linked an issue Dec 11, 2025 that may be closed by this pull request
@Aarekaz Aarekaz added the enhancement New feature or request label Dec 11, 2025
@Aarekaz Aarekaz self-assigned this Dec 11, 2025
@owenmccadden
Copy link
Contributor

image

This is very cool, wonder if we could make it more central / a bigger part of the dashboard?

Nit. I think the spacing might be a bit off here – should the [1] go left of "dashboard"?
image


I think the q option to quit conflicts with the q option for Q chat if you go to the "sessions" menu


Page 21 / 10 (200 lines) • use [[/] or PageUp/PageDown]

It looks like I can exceed the boundaries here, i.e. pagedown past page 10. Also not super clear to me what the use [/] option means. I tried to use / but that triggers the search menu.


I wonder if we should show the full transcript in the sessions view of the dashboard, it feels a bit cluttered for long sessions. Maybe instead have a key shortcut to upload or view in the web UI?

- Updated README to include detailed descriptions of the interactive TUI dashboard and its features.
- Added a new file to .gitignore for todo.md.
- Improved session listing in the TUI by adding date grouping for better organization.
- Enhanced the SessionsView layout for improved readability and navigation.
- Added keyboard shortcuts and usage hints for a better user experience.
- Updated ActivityHeatmap to use double-width blocks for better visual representation of activity levels.
- Adjusted layout in DashboardView to provide a more compact and informative header with inline stats.
- Added calculation for activity streak and average sessions per active day in DashboardView.
- Improved platform breakdown and recent sessions display for clearer insights.
- Enhanced search focus handling in the App component to switch views more intuitively.
- Updated Sidebar component to include separators for better visual organization.
- Improved navigation menu layout and shortcut display for clearer user guidance.
- Compactified authentication status display for a cleaner look.
@Aarekaz
Copy link
Collaborator Author

Aarekaz commented Dec 17, 2025

@owenmccadden, working on some design improvements.

Dashboard:
image

image

Session view:
image

Transcript:

image

I did fix the q issue too.

- Changed Sidebar component to use minWidth for better responsiveness.
- Reduced maxHeight in SessionsView's SessionList for a more compact display.
@Aarekaz Aarekaz marked this pull request as ready for review December 17, 2025 05:57
@Aarekaz Aarekaz requested a review from Copilot December 17, 2025 05:57
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a comprehensive interactive TUI (Text User Interface) dashboard for SessionBase, enabling users to browse, search, filter, and manage AI coding sessions directly from the terminal. The implementation includes a full React-based interface using Ink, custom hooks for data management, and extensive keyboard navigation support.

Key changes:

  • Interactive dashboard command with real-time session statistics, activity heatmaps, and platform breakdowns
  • Sessions browser with search, filtering, sorting, and detailed session views
  • Keyboard-first navigation system with shortcuts for all major operations

Reviewed changes

Copilot reviewed 17 out of 21 changed files in this pull request and generated 28 comments.

Show a summary per file
File Description
src/tui/App.tsx Main React application orchestrating state management, keyboard input handling, and view routing
src/tui/views/DashboardView.tsx Dashboard statistics view with activity heatmap and platform breakdown
src/tui/views/SessionsView.tsx Sessions browser with search, filters, and split-screen detail view
src/tui/components/SessionList.tsx Session listing component with date grouping and rich metadata display
src/tui/components/SearchBar.tsx Interactive search bar component with focus management
src/tui/components/Sidebar.tsx Navigation sidebar with auth status and keyboard shortcuts reference
src/tui/components/ActivityHeatmap.tsx Visual heatmap showing session activity over 28 days
src/tui/components/StatsCard.tsx Reusable statistics card with number formatting
src/tui/components/Box.tsx Bordered box wrapper component for consistent UI framing
src/tui/components/MainContent.tsx Router component switching between dashboard and sessions views
src/tui/hooks/useSessionData.ts Data fetching hook managing sessions, stats, and auth state
src/tui/hooks/useSessionDetail.ts Session detail loading hook with caching and platform-specific parsing
src/tui/types.ts TypeScript type definitions for TUI state and data structures
src/commands/dashboard.ts CLI command implementation launching the Ink-based TUI
src/index.ts CLI command registration for the new dashboard command
package.json Dependencies added for React, Ink, date-fns, and related UI libraries
README.md Comprehensive documentation of dashboard features and keyboard shortcuts
.gitignore Added todo.md to ignored files

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 73 to 84
// #region agent log
fetch('http://127.0.0.1:7242/ingest/2512feb5-b2b3-442f-865d-ae88255c8b60',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'debug-session',runId:'m-toggle',hypothesisId:'H3',location:'useSessionDetail',message:'detail-loaded',data:{filePath:session.filePath,previewCount:previewLines.length,fullCount:fullLines.length},timestamp:Date.now()})}).catch(()=>{});
// #endregion
if (!cancelled) {
setDetail(data);
}
} catch (err: any) {
if (!cancelled) {
setError(err?.message || 'Failed to load session detail');
// #region agent log
fetch('http://127.0.0.1:7242/ingest/2512feb5-b2b3-442f-865d-ae88255c8b60',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'debug-session',runId:'m-toggle',hypothesisId:'H3',location:'useSessionDetail',message:'detail-error',data:{filePath:session?.filePath || null,error:err?.message || 'unknown'},timestamp:Date.now()})}).catch(()=>{});
// #endregion
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains hardcoded debugging/telemetry code that sends data to a localhost endpoint. These fetch calls appear to be agent logging for development purposes and should be removed before merging to production. The hardcoded endpoint and UUID will cause unnecessary network requests in production.

Suggested change
// #region agent log
fetch('http://127.0.0.1:7242/ingest/2512feb5-b2b3-442f-865d-ae88255c8b60',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'debug-session',runId:'m-toggle',hypothesisId:'H3',location:'useSessionDetail',message:'detail-loaded',data:{filePath:session.filePath,previewCount:previewLines.length,fullCount:fullLines.length},timestamp:Date.now()})}).catch(()=>{});
// #endregion
if (!cancelled) {
setDetail(data);
}
} catch (err: any) {
if (!cancelled) {
setError(err?.message || 'Failed to load session detail');
// #region agent log
fetch('http://127.0.0.1:7242/ingest/2512feb5-b2b3-442f-865d-ae88255c8b60',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'debug-session',runId:'m-toggle',hypothesisId:'H3',location:'useSessionDetail',message:'detail-error',data:{filePath:session?.filePath || null,error:err?.message || 'unknown'},timestamp:Date.now()})}).catch(()=>{});
// #endregion
if (!cancelled) {
setDetail(data);
}
} catch (err: any) {
if (!cancelled) {
setError(err?.message || 'Failed to load session detail');

Copilot uses AI. Check for mistakes.
Comment on lines 51 to 57
const platforms = [
{ key: 'all', label: 'All', emoji: '📋' },
{ key: 'claude-code', label: 'Claude', emoji: '🟠' },
{ key: 'gemini-cli', label: 'Gemini', emoji: '🔷' },
{ key: 'qchat', label: 'Q Chat', emoji: '🤖' },
{ key: 'codex', label: 'Codex', emoji: '💜' },
];
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The platform configuration array with keys, labels, and emojis is duplicated across multiple files (DashboardView.tsx, SessionList.tsx, and SessionsView.tsx). This should be extracted to a shared constants file to maintain consistency and make updates easier.

Copilot uses AI. Check for mistakes.
detailOpen: boolean;
detailExpanded: boolean;
detailPage: number;
detail?: any;
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type 'any' is used for the 'detail' prop. Consider creating a proper interface or importing SessionDetailData from the useSessionDetail hook for better type safety.

Copilot uses AI. Check for mistakes.
detailOpen: boolean;
detailExpanded: boolean;
detailPage: number;
detail?: any;
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type 'any' is used for the 'detail' prop. This should use the SessionDetailData type from the useSessionDetail hook for better type safety.

Copilot uses AI. Check for mistakes.

{/* Separator */}
<Box marginBottom={1}>
<Text dimColor>{'─'.repeat(18)}</Text>
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 18 for separator width is hardcoded. This should match the minWidth property (20) minus padding, or be calculated dynamically to ensure the separator line properly fits within the sidebar.

Copilot uses AI. Check for mistakes.
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.17.1",
"@types/react": "^19.2.7",
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @types/react package is listed in dependencies rather than devDependencies. Type definitions are typically development dependencies as they are not needed at runtime. Consider moving this to devDependencies unless there's a specific reason it needs to be a runtime dependency.

Copilot uses AI. Check for mistakes.
>
<Text bold color="cyan">Session Details</Text>
<Text dimColor>
m: more/less • [{`[`}/{`]`} or PageUp/PageDown]: page transcript • Esc: close detail
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keyboard shortcut display uses escaped square brackets ('[[]' and '[]]') which may be confusing. Consider simplifying this to make it more readable, or add a comment explaining this escaping is necessary for the template literal.

Suggested change
m: more/less [{`[`}/{`]`} or PageUp/PageDown]: page transcript Esc: close detail
m: more/less [ [ / ] or PageUp/PageDown ]: page transcript Esc: close detail

Copilot uses AI. Check for mistakes.
height,
padding = 1,
}) => {
const colorFn = (chalk as any)[borderColor] || chalk.cyan;
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable colorFn.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,100 @@
import React from 'react';
import { Box, Text } from 'ink';
import { format, getDay } from 'date-fns';
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import format.

Suggested change
import { format, getDay } from 'date-fns';
import { getDay } from 'date-fns';

Copilot uses AI. Check for mistakes.
};

// Count active days (days with at least one session)
const activeDays = last28Days.filter(d => d.count > 0).length;
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable activeDays.

Suggested change
const activeDays = last28Days.filter(d => d.count > 0).length;

Copilot uses AI. Check for mistakes.
…ed organization and responsiveness

- Moved platform emoji and name functions to constants for better code reuse.
- Updated Sidebar component to dynamically calculate separator width for consistent layout.
- Replaced hardcoded platform data in SessionsView with a centralized PLATFORMS constant for easier maintenance.
- Removed redundant platform functions from SessionList and DashboardView for cleaner code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sb push UX enhancement

3 participants