claude-code-templates
Version:
CLI tool to setup Claude Code configurations with framework-specific commands, automation hooks and MCP Servers for your projects
1,870 lines (1,601 loc) • 238 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Claude Code Analytics - Terminal</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
<!-- Service Scripts (loaded first as dependencies) -->
<script src="services/WebSocketService.js"></script>
<script src="services/DataService.js"></script>
<script src="services/StateService.js"></script>
<!-- Component Scripts -->
<script src="components/HeaderComponent.js"></script>
<script src="components/Charts.js"></script>
<!-- Dashboard.js removed - deprecated architecture -->
<script src="components/ActivityHeatmap.js"></script>
<script src="components/SessionTimer.js"></script>
<script src="components/ConversationTable.js"></script>
<script src="components/ToolDisplay.js"></script>
<script src="components/Sidebar.js"></script>
<script src="components/DashboardPage.js"></script>
<script src="components/App.js"></script>
<!-- main.js removed - deprecated architecture -->
<style>
:root {
/* Dark theme colors (default) */
--bg-primary: #0d1117;
--bg-secondary: #161b22;
--bg-tertiary: #21262d;
--border-primary: #30363d;
--border-secondary: #21262d;
--text-primary: #c9d1d9;
--text-secondary: #7d8590;
--text-accent: #d57455;
--text-success: #3fb950;
--text-warning: #f97316;
--text-error: #f85149;
--text-info: #a5d6ff;
--shadow-primary: rgba(0, 0, 0, 0.4);
--shadow-secondary: rgba(1, 4, 9, 0.85);
}
[data-theme="light"] {
/* Light theme colors */
--bg-primary: #ffffff;
--bg-secondary: #f6f8fa;
--bg-tertiary: #f1f3f4;
--border-primary: #d0d7de;
--border-secondary: #e5e5e5;
--text-primary: #24292f;
--text-secondary: #656d76;
--text-accent: #d73a49;
--text-success: #28a745;
--text-warning: #f97316;
--text-error: #d73a49;
--text-info: #0366d6;
--shadow-primary: rgba(0, 0, 0, 0.1);
--shadow-secondary: rgba(0, 0, 0, 0.2);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
background: var(--bg-primary);
color: var(--text-primary);
min-height: 100vh;
line-height: 1.4;
transition: background-color 0.3s ease, color 0.3s ease;
}
.terminal {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
.terminal-header {
border-bottom: 1px solid var(--border-primary);
padding-bottom: 20px;
margin-bottom: 20px;
position: relative;
}
.terminal-title {
color: var(--text-accent);
font-size: 1.25rem;
font-weight: normal;
display: flex;
align-items: center;
gap: 8px;
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--text-success);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.terminal-subtitle {
color: var(--text-secondary);
font-size: 0.875rem;
margin-top: 4px;
}
.header-actions {
position: absolute;
top: 0;
right: 0;
display: flex;
gap: 8px;
align-items: center;
}
.theme-switch-container {
display: flex;
align-items: center;
font-family: inherit;
}
.theme-switch {
position: relative;
cursor: pointer;
}
.theme-switch-track {
position: relative;
width: 48px;
height: 24px;
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
border-radius: 3px;
transition: all 0.3s ease;
}
.theme-switch-track:hover {
border-color: var(--text-accent);
background: var(--border-primary);
}
.theme-switch-thumb {
position: absolute;
top: 2px;
left: 2px;
width: 18px;
height: 18px;
background: var(--text-accent);
border-radius: 2px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
transform: translateX(0);
}
.theme-switch-thumb.light {
transform: translateX(22px);
}
.theme-switch-icon {
font-size: 0.7rem;
color: var(--bg-primary);
transition: all 0.3s ease;
}
.theme-switch-track::before {
content: '';
position: absolute;
top: -1px;
left: -1px;
right: -1px;
bottom: -1px;
background: linear-gradient(45deg, transparent, var(--text-accent));
border-radius: 3px;
opacity: 0;
transition: opacity 0.3s ease;
z-index: -1;
}
.theme-switch-track:hover::before {
opacity: 0.1;
}
.github-star-btn {
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
color: var(--text-primary);
padding: 8px 12px;
border-radius: 6px;
text-decoration: none;
font-family: inherit;
font-size: 0.875rem;
display: flex;
align-items: center;
gap: 6px;
transition: all 0.2s ease;
cursor: pointer;
}
.github-star-btn:hover {
border-color: var(--text-accent);
background: var(--border-primary);
color: var(--text-accent);
text-decoration: none;
}
.github-star-btn .star-icon {
font-size: 0.75rem;
}
.stats-bar {
display: flex;
gap: 40px;
margin: 20px 0;
flex-wrap: wrap;
}
.stat {
display: flex;
align-items: center;
gap: 8px;
}
.stat-label {
color: #7d8590;
font-size: 0.875rem;
}
.stat-value {
color: #d57455;
font-weight: bold;
}
.stat-sublabel {
color: #7d8590;
font-size: 0.75rem;
display: block;
margin-top: 2px;
}
.token-popover, .claude-sessions-popover {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
margin-top: 8px;
padding: 12px;
background: #21262d;
border: 1px solid #30363d;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
display: none;
z-index: 1000;
min-width: 200px;
white-space: nowrap;
pointer-events: auto;
}
.token-popover::before, .claude-sessions-popover::before {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-bottom-color: #30363d;
}
.token-popover::after, .claude-sessions-popover::after {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border: 5px solid transparent;
border-bottom-color: #21262d;
margin-top: 1px;
}
.token-breakdown-item, .session-breakdown-item {
display: flex;
justify-content: space-between;
margin-bottom: 6px;
font-size: 0.85rem;
}
.token-breakdown-item:last-child, .session-breakdown-item:last-child {
margin-bottom: 0;
}
.token-type, .session-type {
color: #7d8590;
}
.token-value, .session-value {
color: #c9d1d9;
font-weight: 500;
}
.chart-controls {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin: 20px 0;
padding: 12px 0;
border-top: 1px solid #21262d;
border-bottom: 1px solid #21262d;
}
.chart-controls-left {
display: flex;
align-items: center;
gap: 16px;
}
.chart-controls-right {
display: flex;
align-items: center;
gap: 12px;
}
.date-control {
display: flex;
align-items: center;
gap: 8px;
}
.date-label {
color: #7d8590;
font-size: 0.875rem;
}
.date-input {
background: #21262d;
border: 1px solid #30363d;
color: #c9d1d9;
padding: 6px 12px;
border-radius: 4px;
font-family: inherit;
font-size: 0.875rem;
cursor: pointer;
}
.date-input:focus {
outline: none;
border-color: #d57455;
}
.refresh-btn {
background: none;
border: 1px solid #30363d;
color: #7d8590;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-family: inherit;
font-size: 0.875rem;
transition: all 0.2s ease;
display: flex;
align-items: center;
gap: 6px;
}
.refresh-btn:hover {
border-color: #d57455;
color: #d57455;
}
.refresh-btn.loading {
opacity: 0.6;
cursor: not-allowed;
}
/* Action Buttons Container */
.action-buttons-container {
display: flex;
justify-content: flex-end;
gap: 8px;
margin: 8px 0 16px 0;
padding: 0;
}
/* Small Action Buttons */
.action-btn-small {
/* Reset browser defaults */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 1px solid var(--border-primary);
outline: none;
/* Custom styles */
background: var(--bg-tertiary);
color: var(--text-secondary);
padding: 4px 8px;
border-radius: 4px;
cursor: pointer;
font-family: inherit;
font-size: 0.75rem;
transition: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
display: flex;
align-items: center;
gap: 4px;
min-width: 80px;
width: auto;
height: 24px;
white-space: nowrap;
box-sizing: border-box;
/* Force fixed dimensions */
max-width: 80px;
overflow: hidden;
}
.action-btn-small:hover {
border-color: var(--text-accent);
color: var(--text-accent);
background: var(--bg-secondary);
}
.action-btn-small:active {
opacity: 0.8;
transform: none !important;
scale: none !important;
}
.action-btn-small:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none !important;
}
/* Prevent any size changes on action buttons */
.action-btn-small,
.action-btn-small:hover,
.action-btn-small:active,
.action-btn-small:focus,
.action-btn-small.loading {
transform: none !important;
scale: none !important;
height: 24px !important;
min-width: 80px !important;
max-width: 80px !important;
padding: 4px 8px !important;
border-width: 1px !important;
box-sizing: border-box !important;
white-space: nowrap !important;
overflow: hidden !important;
}
.action-btn-small.loading {
opacity: 0.7;
pointer-events: none;
}
.btn-icon-small {
font-size: 0.7rem;
line-height: 1;
display: inline-block;
width: 10px;
text-align: center;
}
/* Animation for refresh button */
.btn-icon-small.spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.last-update-info {
color: #7d8590;
font-size: 0.875rem;
margin: 8px 0 16px 0;
padding: 8px 0;
border-bottom: 1px solid #21262d;
}
.last-update-label {
color: #7d8590;
}
.date-separator {
color: #7d8590;
font-size: 0.875rem;
}
.filter-label {
color: #7d8590;
font-size: 0.875rem;
}
.filter-btn {
background: none;
border: 1px solid #30363d;
color: #7d8590;
padding: 4px 12px;
border-radius: 4px;
cursor: pointer;
font-family: inherit;
font-size: 0.875rem;
transition: all 0.2s ease;
}
.filter-btn:hover {
border-color: #d57455;
color: #d57455;
}
.filter-btn.active {
background: #d57455;
border-color: #d57455;
color: #0d1117;
}
.charts-container {
display: grid;
grid-template-columns: 2fr 1fr 2fr 1fr;
gap: 30px;
margin: 20px 0 30px 0;
}
.chart-card {
background: #161b22;
border: 1px solid #30363d;
border-radius: 6px;
padding: 20px;
position: relative;
}
.chart-title {
color: #d57455;
font-size: 0.875rem;
text-transform: uppercase;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
}
.chart-canvas {
width: 100% !important;
height: 200px !important;
}
.tool-summary {
padding: 20px;
height: 200px;
display: flex;
flex-direction: column;
gap: 12px;
overflow-y: auto;
}
.tool-stat {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
background: var(--bg-tertiary);
border: 1px solid var(--border-secondary);
border-radius: 4px;
transition: all 0.2s ease;
font-size: 0.8rem;
}
.tool-stat:hover {
background: var(--bg-secondary);
border-color: var(--border-primary);
}
.tool-stat-label {
color: var(--text-secondary);
font-weight: 500;
}
.tool-stat-value {
color: var(--text-primary);
font-weight: 600;
}
.tool-stat-accent {
color: var(--text-accent);
}
.tool-top-tool {
display: flex;
align-items: center;
gap: 8px;
padding: 12px;
background: var(--bg-tertiary);
border: 1px solid var(--border-secondary);
border-radius: 4px;
margin-top: auto;
}
.tool-icon {
width: 24px;
height: 24px;
background: var(--text-accent);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: white;
}
.tool-info {
flex: 1;
}
.tool-name {
color: var(--text-primary);
font-size: 0.8rem;
font-weight: 600;
margin-bottom: 2px;
}
.tool-usage {
color: var(--text-secondary);
font-size: 0.7rem;
}
/* Session Timer Accordion Styles */
.session-timer-section {
margin: 15px 0;
}
.session-timer-accordion {
background: var(--bg-secondary);
border: 1px solid var(--border-primary);
border-radius: 6px;
margin-bottom: 15px;
position: relative;
}
.session-timer-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
cursor: pointer;
border-bottom: 1px solid var(--border-primary);
transition: background-color 0.2s ease;
}
.session-timer-header:hover {
background: var(--bg-tertiary);
}
.session-timer-title-section {
display: flex;
align-items: center;
gap: 8px;
}
.session-timer-chevron {
font-size: 0.75rem;
color: var(--text-secondary);
transition: transform 0.2s ease;
}
.session-timer-title {
color: var(--text-accent);
font-size: 0.9rem;
font-weight: 500;
margin: 0;
}
.session-timer-status-inline {
display: flex;
align-items: center;
gap: 6px;
font-size: 0.75rem;
}
.session-timer-status-dot {
width: 6px;
height: 6px;
border-radius: 50%;
animation: pulse 2s infinite;
}
.session-timer-status-dot.active {
background: #3fb950;
}
.session-timer-status-dot.warning {
background: #f97316;
}
.session-timer-status-dot.inactive {
background: #7d8590;
}
.session-timer-status-text {
color: var(--text-primary);
}
.session-timer-content {
padding: 12px 16px;
border-top: none;
}
.session-loading-state {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 20px 0;
color: #7d8590;
}
.session-spinner {
width: 16px;
height: 16px;
border: 2px solid #30363d;
border-top: 2px solid #d57455;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.session-timer-empty {
text-align: center;
padding: 20px;
}
.session-timer-empty-text {
color: var(--text-primary);
font-size: 0.9rem;
margin-bottom: 4px;
}
.session-timer-empty-subtext {
color: var(--text-secondary);
font-size: 0.8rem;
}
.session-timer-compact {
display: flex;
flex-direction: column;
gap: 12px;
}
.session-timer-row {
display: flex;
gap: 20px;
align-items: center;
}
.session-timer-time-compact {
flex: 0 0 auto;
text-align: center;
}
.session-timer-time-value {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-accent);
line-height: 1;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}
.session-timer-time-label {
color: var(--text-secondary);
font-size: 0.75rem;
margin-top: 2px;
}
.session-timer-progress-compact {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
}
.session-timer-progress-item {
display: flex;
flex-direction: column;
gap: 4px;
}
.session-timer-progress-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.session-timer-progress-label {
color: var(--text-primary);
font-size: 0.75rem;
font-weight: 500;
}
.session-timer-progress-value {
color: var(--text-secondary);
font-size: 0.75rem;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
display: inline-flex;
align-items: center;
}
.session-timer-progress-bar {
width: 100%;
height: 4px;
background: var(--border-primary);
border-radius: 2px;
overflow: hidden;
position: relative;
}
.session-timer-progress-fill {
height: 100%;
background: var(--text-success);
transition: width 0.3s ease, background-color 0.3s ease;
border-radius: 2px;
}
.session-timer-stats-row {
display: flex;
gap: 12px;
padding-top: 8px;
border-top: 1px solid var(--border-primary);
flex-wrap: wrap;
}
.session-timer-stat-compact {
display: flex;
align-items: center;
gap: 4px;
flex: 1;
min-width: 0;
}
.session-timer-stat-label {
color: var(--text-secondary);
font-size: 0.75rem;
white-space: nowrap;
}
.session-timer-stat-value {
color: var(--text-primary);
font-weight: 500;
font-size: 0.75rem;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.session-timer-error {
text-align: center;
padding: 20px;
color: var(--text-error);
}
.session-timer-error-text {
margin-bottom: 12px;
font-size: 0.85rem;
}
.session-timer-retry-btn {
background: var(--text-error);
border: 1px solid var(--text-error);
color: var(--bg-primary);
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-size: 0.75rem;
transition: all 0.2s ease;
}
.session-timer-retry-btn:hover {
opacity: 0.8;
}
.session-warnings {
margin-top: 8px;
}
.warnings-list {
display: flex;
flex-direction: column;
gap: 4px;
}
.session-warning {
background: rgba(248, 81, 73, 0.1);
border: 1px solid rgba(248, 81, 73, 0.3);
border-radius: 4px;
padding: 8px;
color: #ffa198;
font-size: 0.75rem;
display: flex;
align-items: center;
gap: 6px;
}
.session-warning.error {
background: rgba(248, 81, 73, 0.15);
border-color: rgba(248, 81, 73, 0.5);
}
.session-warning.warning {
background: rgba(249, 115, 22, 0.1);
border-color: rgba(249, 115, 22, 0.3);
color: #fbbf24;
}
.session-warning.info {
background: rgba(59, 130, 246, 0.1);
border-color: rgba(59, 130, 246, 0.3);
color: #93c5fd;
}
/* Session Timer Info Icon and Popover */
.session-timer-label-with-info {
display: inline-flex;
align-items: center;
gap: 4px;
}
.session-timer-info-icon {
color: var(--text-secondary);
font-size: 0.7rem;
cursor: pointer;
transition: all 0.2s ease;
display: inline-flex;
align-items: center;
margin-left: 4px;
opacity: 0.6;
line-height: 1;
vertical-align: middle;
padding: 2px;
border-radius: 2px;
}
.session-timer-info-icon:hover {
color: var(--text-info);
opacity: 1;
background-color: rgba(88, 166, 255, 0.1);
}
.session-timer-info-icon:active {
background-color: rgba(88, 166, 255, 0.2);
}
.session-timer-tooltip {
position: absolute;
z-index: 1000;
background: var(--bg-primary);
border: 1px solid var(--border-primary);
border-radius: 6px;
padding: 0;
box-shadow: 0 16px 32px rgba(1, 4, 9, 0.85);
max-width: 300px;
font-size: 0.75rem;
line-height: 1.4;
}
.session-timer-tooltip-content {
padding: 12px;
}
.session-timer-tooltip-content h4 {
margin: 0 0 8px 0;
color: var(--text-primary);
font-size: 0.8rem;
font-weight: 600;
}
.session-timer-tooltip-content p {
margin: 0 0 8px 0;
color: var(--text-primary);
line-height: 1.5;
}
.session-timer-tooltip-content p:last-of-type {
margin-bottom: 12px;
}
.session-timer-tooltip-link {
border-top: 1px solid var(--border-primary);
padding-top: 8px;
}
.session-timer-tooltip-link a {
color: var(--text-info);
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 4px;
transition: color 0.2s ease;
}
.session-timer-tooltip-link a:hover {
opacity: 0.8;
}
.session-timer-tooltip-link i {
font-size: 0.65rem;
}
/* Claude Session Info Styles */
.claude-session-info {
background: #161b22;
border: 1px solid #30363d;
border-radius: 6px;
padding: 12px;
margin: 12px 0;
}
.claude-session-info-row {
margin-bottom: 12px;
}
.claude-session-info-compact {
padding: 8px 12px;
background: #0d1117;
border: 1px solid #21262d;
border-radius: 4px;
}
.claude-session-header {
color: #d57455;
font-size: 0.8rem;
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.claude-session-details {
display: flex;
flex-direction: column;
gap: 4px;
}
.claude-session-stats {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.claude-session-stat {
display: flex;
align-items: center;
gap: 4px;
}
.claude-session-label {
color: #7d8590;
font-size: 0.75rem;
}
.claude-session-value {
color: #c9d1d9;
font-size: 0.75rem;
font-weight: 600;
}
.claude-session-value.expired {
color: #f85149;
}
.session-timer-status-dot.expired {
background: #f85149;
animation: pulse 2s infinite;
}
.charts-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin: 20px 0 30px 0;
}
.chart-card {
background: #161b22;
border: 1px solid #30363d;
border-radius: 6px;
padding: 20px;
position: relative;
}
.chart-title {
color: #d57455;
font-size: 0.875rem;
text-transform: uppercase;
margin-bottom: 16px;
display: flex;
align-items: center;
gap: 8px;
}
.chart-canvas {
width: 100% !important;
height: 200px !important;
}
.tool-summary {
padding: 20px;
height: 200px;
display: flex;
flex-direction: column;
gap: 12px;
overflow-y: auto;
}
.tool-stat {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
background: var(--bg-tertiary);
border: 1px solid var(--border-secondary);
border-radius: 4px;
transition: all 0.2s ease;
font-size: 0.8rem;
}
.tool-stat:hover {
background: var(--bg-secondary);
border-color: var(--border-primary);
}
.tool-stat-label {
color: var(--text-secondary);
font-weight: 500;
}
.tool-stat-value {
color: var(--text-primary);
font-weight: 600;
}
.tool-stat-accent {
color: var(--text-accent);
}
.tool-top-tool {
display: flex;
align-items: center;
gap: 8px;
padding: 12px;
background: var(--bg-tertiary);
border: 1px solid var(--border-secondary);
border-radius: 4px;
margin-top: auto;
}
.tool-icon {
width: 24px;
height: 24px;
background: var(--text-accent);
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: white;
}
.tool-info {
flex: 1;
}
.tool-name {
color: var(--text-primary);
font-size: 0.8rem;
font-weight: 600;
margin-bottom: 2px;
}
.tool-usage {
color: var(--text-secondary);
font-size: 0.7rem;
}
.filter-bar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin: 20px 0;
padding: 12px 0;
border-top: 1px solid #21262d;
border-bottom: 1px solid #21262d;
}
.filter-section {
display: flex;
align-items: center;
gap: 16px;
}
.filter-label {
color: #7d8590;
font-size: 0.875rem;
}
.filter-buttons {
display: flex;
gap: 8px;
}
.filter-actions {
display: flex;
align-items: center;
}
.filter-btn {
background: none;
border: 1px solid #30363d;
color: #7d8590;
padding: 4px 12px;
border-radius: 4px;
cursor: pointer;
font-family: inherit;
font-size: 0.875rem;
transition: all 0.2s ease;
}
.filter-btn:hover {
border-color: #d57455;
color: #d57455;
}
.filter-btn.active {
background: #d57455;
border-color: #d57455;
color: #0d1117;
}
.sessions-table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
.sessions-table th {
text-align: left;
padding: 8px 12px;
color: #7d8590;
font-size: 0.875rem;
font-weight: normal;
border-bottom: 1px solid #30363d;
}
.sessions-table th:nth-child(1) { width: 20%; } /* conversation id */
.sessions-table th:nth-child(2) { width: 15%; } /* project */
.sessions-table th:nth-child(3) { width: 10%; } /* model */
.sessions-table th:nth-child(4) { width: 8%; } /* messages */
.sessions-table th:nth-child(5) { width: 10%; } /* tokens */
.sessions-table th:nth-child(6) { width: 12%; } /* last activity */
.sessions-table th:nth-child(7) { width: 15%; } /* conversation state - FIXED WIDTH */
.sessions-table th:nth-child(8) { width: 10%; } /* status */
.sessions-table td {
padding: 8px 12px;
font-size: 0.875rem;
border-bottom: 1px solid #21262d;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Allow status squares to wrap and flex */
.sessions-table td:nth-child(8) {
white-space: normal;
overflow: visible;
}
/* Allow conversation id to wrap for long IDs */
.sessions-table td:nth-child(1) {
white-space: normal;
overflow: visible;
}
.sessions-table tr:hover {
background: #161b22;
}
.session-id {
color: #d57455;
font-family: monospace;
display: flex;
align-items: center;
gap: 6px;
}
.process-indicator {
display: inline-block;
width: 6px;
height: 6px;
background: #3fb950;
border-radius: 50%;
animation: pulse 2s infinite;
cursor: help;
}
.process-indicator.orphan {
background: #f85149;
}
.session-id-container {
display: flex;
flex-direction: column;
gap: 4px;
}
.session-project {
color: #c9d1d9;
}
.session-model {
color: #a5d6ff;
font-size: 0.8rem;
max-width: 150px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.session-messages {
color: #7d8590;
}
.session-tokens {
color: #f85149;
}
.session-time {
color: #7d8590;
font-size: 0.8rem;
}
.status-active {
color: #3fb950;
font-weight: bold;
}
.status-recent {
color: #d29922;
}
.status-inactive {
color: #7d8590;
}
.conversation-state {
color: #d57455;
font-style: italic;
font-size: 0.8rem;
}
.conversation-state.working {
animation: working-pulse 1.5s infinite;
}
.conversation-state.typing {
animation: typing-pulse 1.5s infinite;
}
@keyframes working-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
@keyframes typing-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.status-squares {
display: flex;
gap: 2px;
align-items: center;
flex-wrap: wrap;
margin: 0;
padding: 0;
}
.status-square {
width: 10px !important;
height: 10px !important;
min-width: 10px !important;
min-height: 10px !important;
max-width: 10px !important;
max-height: 10px !important;
border-radius: 2px;
cursor: help;
position: relative;
flex-shrink: 0;
box-sizing: border-box;
}
.status-square.success {
background: #d57455;
}
.status-square.tool {
background: #f97316;
}
.status-square.error {
background: #dc2626;
}
.status-square.pending {
background: #6b7280;
}
/* Additional specificity to override any table styling */
.sessions-table .status-squares .status-square {
width: 10px !important;
height: 10px !important;
min-width: 10px !important;
min-height: 10px !important;
max-width: 10px !important;
max-height: 10px !important;
display: inline-block !important;
font-size: 0 !important;
line-height: 0 !important;
border: none !important;
outline: none !important;
vertical-align: top !important;
}
.status-square:hover::after {
content: attr(data-tooltip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: #1c1c1c;
color: #fff;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.75rem;
white-space: nowrap;
z-index: 1000;
margin-bottom: 4px;
border: 1px solid #30363d;
}
.status-square:hover::before {
content: '';
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
border: 4px solid transparent;
border-top-color: #30363d;
z-index: 1000;
}
.loading, #error {
text-align: center;
padding: 40px;
color: #7d8590;
}
#error {
color: #f85149;
}
.no-sessions {
text-align: center;
padding: 40px;
color: #7d8590;
font-style: italic;
}
.session-detail {
display: none;
margin-top: 20px;
}
.session-detail.active {
display: block;
}
.detail-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 0;
border-bottom: 1px solid #30363d;
margin-bottom: 20px;
}
.detail-title {
color: #d57455;
font-size: 1.1rem;
}
.detail-actions {
display: flex;
gap: 12px;
align-items: center;
}
.export-format-select {
background: #21262d;
border: 1px solid #30363d;
color: #c9d1d9;
padding: 6px 12px;
border-radius: 4px;
font-family: inherit;
font-size: 0.875rem;
cursor: pointer;
}
.export-format-select:focus {
outline: none;
border-color: #d57455;
}
.export-format-select option {
background: #21262d;
color: #c9d1d9;
}
.btn {
background: none;
border: 1px solid #30363d;
color: #7d8590;
padding: 6px 12px;
border-radius: 4px;
cursor: pointer;
font-family: inherit;
font-size: 0.875rem;
transition: all 0.2s ease;
}
.btn:hover {
border-color: #d57455;
color: #d57455;
}
.btn-primary {
background: #d57455;
border-color: #d57455;
color: #0d1117;
}
.btn-primary:hover {
background: #e8956f;
border-color: #e8956f;
}
.session-info {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.info-item {
display: flex;
flex-direction: column;
gap: 4px;
}
.info-label {
color: #7d8590;
font-size: 0.75rem;
text-transform: uppercase;
}
.info-value {
color: #c9d1d9;
font-size: 0.875rem;
}
.info-value.model {
color: #a5d6ff;
font-weight: bold;
}
.search-input {
width: 100%;
background: #21262d;
border: 1px solid #30363d;
color: #c9d1d9;
padding: 8px 12px;
border-radius: 4px;
font-family: inherit;
font-size: 0.875rem;
margin-bottom: 16px;
}
.search-input:focus {
outline: none;
border-color: #d57455;
}
.conversation-history {
border: 1px solid #30363d;
border-radius: 6px;
max-height: 600px;
overflow-y: auto;
}
.message {
padding: 16px;
border-bottom: 1px solid #21262d;
position: relative;
}
.message-metadata {
margin: 8px 0;
padding: 4px 8px;
background: #161b22;
border-radius: 4px;
border-left: 2px solid #30363d;
}
.message-id {
margin-top: 8px;
text-align: right;
opacity: 0.7;
}
.message:last-child {
border-bottom: none;
}
.message-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.message-role {
color: #58a6ff;
font-size: 0.875rem;
font-weight: bold;
}
.message-role.user {
color: #3fb950;
}
.message-role.assistant {
color: #d57455;
}
.message-time {
color: white;
font-size: 0.75rem;
}
.message-content {
color: #c9d1d9;
font-size: 0.875rem;
line-height: 1.5;
white-space: pre-wrap;
word-wrap: break-word;
}
.message-type-indicator {
position: absolute;
top: 8px;
right: 8px;
width: 8px;
height: 8px;
border-radius: 2px;
cursor: help;
}
.message-type-indicator.success {
background: #d57455;
}
.message-type-indicator.tool {
background: #f97316;
}
.message-type-indicator.error {
background: #dc2626;
}
.message-type-indicator.pending {
background: #6b7280;
}
.message-type-indicator:hover::after {
content: attr(data-tooltip);
position: absolute;
top: 100%;
right: 0;
background: #1c1c1c;
color: #fff;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.75rem;
white-space: nowrap;
z-index: 1000;
margin-top: 4px;
border: 1px solid #30363d;
}
/* Terminal Chat Styles */
.messages-list {
display: flex;
flex-direction: column;
gap: 12px;
padding: 8px;
}
.terminal-message {
display: flex;
width: 100%;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 0.85rem;
line-height: 1.3;
min-width: 0;
}
.terminal-message.user {
justify-content: flex-end;
}
.terminal-message.assistant {
justify-content: flex-start;
}
.message-container {
max-width: 75%;
background: var(--bg-tertiary);
border: 1px solid var(--border-primary);
border-radius: 6px;
padding: 10px 12px;
position: relative;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
word-wrap: break-word;
overflow-wrap: break-word;
min-width: 0;
}
.terminal-message.user .message-container {
background: var(--bg-secondary);
border: 1px solid rgba(63, 185, 80, 0.3);
border-left: 4px solid var(--text-success);
}
.terminal-message.assistant .message-container {
background: var(--bg-tertiary);
border: 1px solid rgba(213, 116, 85, 0.3);
border-left: 4px solid var(--text-accent);
}
/* Terminal window effect */
.message-container::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: var(--border-secondary);
border-radius: 6px 6px 0 0;
}
.terminal-message.user .message-container::before {
background: rgba(63, 185, 80, 0.2);
}
.terminal-message.assistant .message-container::before {
background: rgba(213, 116, 85, 0.2);
}
.message-prompt {
display: flex;
align-items: center;
gap: 8px;
color: var(--text-secondary);
font-size: 0.8rem;
margin-bottom: 6px;
}
.message-type-indicator {
display: inline-block;
border-radius: 2px;
width: 12px;
height: 12px;
vertical-align: baseline;
margin-top: 2px;
}
.type-icon {
display: none;
}
.type-label {
display: none;
}
/* Message Type Colors */
.type-user-input {
background: rgba(63, 185, 80, 0.2);
color: var(--text-success);
border: 1px solid rgba(63, 185, 80, 0.4);
}
.type-tool-result {
background: rgba(168, 85, 247, 0.2);
color: #a855f7;
border: 1px solid rgba(168, 85, 247, 0.4);
}
.type-response {
background: rgba(59, 130, 246, 0.2);
color: #3b82f6;
border: 1px solid rgba(59, 130, 246, 0.4);
}
.type-tools-only {
background: rgba(249, 115, 22, 0.2);
color: #f97316;
border: 1px solid rgba(249, 115, 22, 0.4);
}
.type-response-tools {
background: rgba(213, 116, 85, 0.2);
color: var(--text-accent);
border: 1px solid rgba(213, 116, 85, 0.4);
}
.type-compact-summary {
background: rgba(165, 214, 255, 0.2);
color: var(--text-info);
border: 1px solid rgba(165, 214, 255, 0.4);
}
/* Show Results Button */
.show-results-btn {
background: var(--text-accent);
color: white;
border: none;
padding: 2px 6px;
margin-left: 8px;