2026-01-18 05:14:34 +01:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
2026-01-18 22:04:02 +01:00
< meta name = "description" content = "Claude Code session manager with web interface" >
< meta name = "theme-color" content = "#0a0a0a" >
2026-01-18 05:14:34 +01:00
< title > Claudeman</ title >
2026-01-18 22:04:02 +01:00
< link rel = "icon" type = "image/svg+xml" href = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%2360a5fa'/%3E%3Cstop offset='100%25' stop-color='%233b82f6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='32' height='32' rx='6' fill='%230a0a0a'/%3E%3Cpath d='M18 4L8 18h6l-2 10 10-14h-6z' fill='url(%23g)'/%3E%3C/svg%3E" >
2026-01-18 05:14:34 +01:00
< link rel = "stylesheet" href = "styles.css" >
2026-01-18 07:31:19 +01:00
< link rel = "stylesheet" href = "https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css" >
< script src = "https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.min.js" ></ script >
< script src = "https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.min.js" ></ script >
2026-01-18 05:14:34 +01:00
</ head >
< body >
< div class = "app" >
2026-01-19 00:38:11 +01:00
<!-- Compact Header with Session Tabs -->
2026-01-18 05:14:34 +01:00
< header class = "header" >
2026-01-19 00:38:11 +01:00
< div class = "header-brand" >
< span class = "logo" > Claudeman</ span >
</ div >
<!-- Session Tabs -->
< div class = "session-tabs" id = "sessionTabs" >
2026-01-18 05:14:34 +01:00
</ div >
2026-01-19 00:38:11 +01:00
< div class = "header-right" >
2026-01-19 02:48:28 +01:00
< div class = "header-font-controls" >
< button class = "btn-icon-header btn-sm" onclick = "app.decreaseFontSize()" title = "Decrease font (Ctrl+-)" > A-</ button >
< span class = "font-size-display" id = "fontSizeDisplay" > 14</ span >
< button class = "btn-icon-header btn-sm" onclick = "app.increaseFontSize()" title = "Increase font (Ctrl++)" > A+</ button >
</ div >
2026-01-19 06:51:25 +01:00
< div class = "header-system-stats" id = "headerSystemStats" title = "System resource usage" >
2026-01-19 10:36:30 +01:00
< div class = "stat-item" >
< span class = "stat-label" > CPU</ span >
< div class = "stat-bar" >
< div class = "stat-bar-fill stat-bar-cpu" id = "statCpuBar" ></ div >
</ div >
< span class = "stat-value" id = "statCpu" > --%</ span >
</ div >
2026-01-24 19:57:28 +01:00
< div class = "stat-item" >
< span class = "stat-label" > MEM</ span >
< div class = "stat-bar" >
< div class = "stat-bar-fill stat-bar-mem" id = "statMemBar" ></ div >
</ div >
< span class = "stat-value" id = "statMem" > --</ span >
</ div >
2026-01-19 06:51:25 +01:00
</ div >
2026-01-24 01:22:53 +01:00
< button class = "btn-icon-header btn-notifications" onclick = "app.toggleNotifications()" title = "Notifications" >
2026-01-24 19:45:37 +01:00
< svg width = "16" height = "16" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< path d = "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" />< path d = "M13.73 21a2 2 0 0 1-3.46 0" /></ svg >
2026-01-24 01:22:53 +01:00
< span class = "notification-badge" id = "notifBadge" style = "display:none;" > 0</ span >
</ button >
2026-01-24 19:51:24 +01:00
< button class = "btn-icon-header btn-settings" onclick = "app.openAppSettings()" title = "App Settings" >< svg width = "16" height = "16" viewBox = "0 0 24 24" fill = "none" stroke = "currentColor" stroke-width = "2" stroke-linecap = "round" stroke-linejoin = "round" >< circle cx = "12" cy = "12" r = "3" />< path d = "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" /></ svg ></ button >
2026-01-19 11:36:13 +01:00
< div class = "header-tokens" id = "headerTokens" title = "Total tokens across all sessions" > 0 tokens</ div >
2026-01-18 05:14:34 +01:00
</ div >
</ header >
<!-- Timer Banner (shown when timed run is active) -->
< div class = "timer-banner" id = "timerBanner" style = "display: none;" >
2026-01-19 00:38:11 +01:00
< div class = "timer-content" >
2026-01-18 05:14:34 +01:00
< span class = "timer-value" id = "timerValue" > 00:00:00</ span >
2026-01-19 00:38:11 +01:00
< div class = "timer-progress" >< div class = "timer-progress-fill" id = "timerProgress" ></ div ></ div >
< span class = "timer-meta" id = "timerMeta" > 0 tasks | $0.00</ span >
2026-01-18 05:14:34 +01:00
</ div >
2026-01-19 00:38:11 +01:00
< button class = "btn-icon-only" onclick = "app.stopCurrentRun()" title = "Stop" > ■ </ button >
2026-01-18 05:14:34 +01:00
</ div >
2026-01-19 00:38:11 +01:00
<!-- Respawn Banner -->
2026-01-18 07:31:19 +01:00
< div class = "respawn-banner" id = "respawnBanner" style = "display: none;" >
2026-01-25 03:57:44 +01:00
< div class = "respawn-banner-row" >
< span class = "respawn-indicator" > ↻ </ span >
< span class = "respawn-state" id = "respawnState" > Watching</ span >
2026-01-25 04:57:09 +01:00
< span class = "detection-status" id = "detectionStatus" ></ span >
< span class = "detection-waiting" id = "detectionWaiting" style = "display: none;" ></ span >
< span class = "detection-confidence" id = "detectionConfidence" ></ span >
2026-01-25 21:29:35 +01:00
< span class = "detection-hook" id = "detectionHook" style = "display: none;" ></ span >
2026-01-25 04:57:09 +01:00
< span class = "detection-ai-check" id = "detectionAiCheck" style = "display: none;" ></ span >
< span class = "respawn-spacer" ></ span >
< span class = "respawn-cycles" > #< span id = "respawnCycleCount" > 0</ span ></ span >
2026-01-25 03:57:44 +01:00
< span class = "respawn-timer" id = "respawnTimer" style = "display: none;" ></ span >
< span class = "respawn-tokens" id = "respawnTokens" style = "display: none;" ></ span >
< button class = "btn-icon-only" onclick = "app.stopRespawn()" title = "Stop Respawn" > ■ </ button >
</ div >
< div class = "respawn-timers-row" id = "respawnTimersRow" style = "display: none;" >
2026-01-25 04:57:09 +01:00
< div class = "respawn-countdown-timers" id = "respawnCountdownTimers" ></ div >
< div class = "respawn-action-log" id = "respawnActionLog" ></ div >
2026-01-25 03:57:44 +01:00
</ div >
2026-01-18 07:31:19 +01:00
</ div >
2026-01-21 22:36:45 +01:00
<!-- Ralph / Todo Tracker Panel -->
< div class = "ralph-panel collapsed" id = "ralphStatePanel" style = "display: none;" >
2026-01-19 17:09:56 +01:00
<!-- Collapsed Summary Bar -->
2026-01-19 18:41:14 +01:00
< div class = "ralph-summary" id = "ralphSummary" >
2026-01-21 22:36:45 +01:00
< div class = "ralph-summary-content" onclick = "app.toggleRalphStatePanel()" >
2026-01-19 18:41:14 +01:00
< div class = "ralph-ring-mini" id = "ralphRingMini" >
< svg viewBox = "0 0 36 36" class = "ralph-ring-svg" >
2026-01-20 20:00:57 +01:00
< defs >
< linearGradient id = "ralphGradientMini" x1 = "0%" y1 = "0%" x2 = "100%" y2 = "100%" >
< stop offset = "0%" stop-color = "#3b82f6" />
< stop offset = "100%" stop-color = "#22c55e" />
</ linearGradient >
</ defs >
2026-01-19 18:41:14 +01:00
< circle class = "ralph-ring-bg" cx = "18" cy = "18" r = "15.9" />
2026-01-20 20:00:57 +01:00
< circle class = "ralph-ring-progress-mini" cx = "18" cy = "18" r = "15.9" id = "ralphRingMiniProgress" />
2026-01-19 18:41:14 +01:00
</ svg >
< span class = "ralph-ring-text" id = "ralphRingMiniText" > 0%</ span >
</ div >
< div class = "ralph-summary-info" >
2026-01-21 22:36:45 +01:00
< span class = "ralph-title" > Ralph / Todo Tracker</ span >
2026-01-19 18:41:14 +01:00
< span class = "ralph-status-badge" id = "ralphStatusBadge" >
< span class = "ralph-status-dot" ></ span >
< span class = "ralph-status-text" > Idle</ span >
</ span >
</ div >
< div class = "ralph-summary-stats" >
< span class = "ralph-stat" >< span class = "ralph-stat-icon" > ⏱ </ span >< span id = "ralphStatTime" > 0m</ span ></ span >
< span class = "ralph-stat" >< span class = "ralph-stat-icon" > ✓ </ span >< span id = "ralphStatTasks" > 0/0</ span ></ span >
</ div >
2026-01-20 18:56:55 +01:00
< span class = "ralph-toggle" id = "ralphToggle" > ▼ </ span >
2026-01-19 17:09:56 +01:00
</ div >
2026-01-19 18:41:14 +01:00
< div class = "ralph-controls" >
2026-01-20 17:37:49 +01:00
< button class = "btn-icon-sm" onclick = "event.stopPropagation(); app.toggleRalphDetach()" title = "Detach/Attach panel" id = "ralphDetachBtn" > ⧉ </ button >
2026-01-20 17:54:59 +01:00
< button class = "btn-icon-sm" onclick = "event.stopPropagation(); app.closeRalphTracker()" title = "Close tracker" > × </ button >
2026-01-19 17:09:56 +01:00
</ div >
</ div >
2026-01-20 17:59:34 +01:00
<!-- Expanded Detail View - Compact horizontal layout -->
2026-01-19 17:09:56 +01:00
< div class = "ralph-detail" id = "ralphDetail" >
2026-01-20 17:59:34 +01:00
< div class = "ralph-detail-row" >
<!-- Progress Ring -->
< div class = "ralph-ring-compact" >
2026-01-19 17:09:56 +01:00
< svg viewBox = "0 0 100 100" class = "ralph-ring-svg-large" >
< defs >
< linearGradient id = "ralphGradient" x1 = "0%" y1 = "0%" x2 = "100%" y2 = "100%" >
< stop offset = "0%" stop-color = "#3b82f6" />
< stop offset = "100%" stop-color = "#22c55e" />
</ linearGradient >
</ defs >
< circle class = "ralph-ring-track" cx = "50" cy = "50" r = "42" />
< circle class = "ralph-ring-fill" cx = "50" cy = "50" r = "42" id = "ralphRingProgress" />
</ svg >
< div class = "ralph-ring-center" >
< div class = "ralph-ring-percent" id = "ralphRingPercent" > 0%</ div >
< div class = "ralph-ring-label" > Complete</ div >
</ div >
</ div >
2026-01-20 20:26:04 +01:00
<!-- Meta Info + Tasks unified -->
< div class = "ralph-info-unified" >
< div class = "ralph-info-labels" >
< div class = "ralph-info-row" >
2026-01-20 20:35:00 +01:00
< span class = "ralph-info-label" > Tasks</ span >
< span class = "ralph-tasks-count" id = "ralphTasksCount" > 0/0</ span >
</ div >
< div class = "ralph-info-row" >
< span class = "ralph-info-label" > Phrase</ span >
2026-01-20 20:26:04 +01:00
< code id = "ralphPhrase" > --</ code >
</ div >
< div class = "ralph-info-row" >
< span class = "ralph-info-label" > Elapsed</ span >
< span id = "ralphElapsed" > 0m</ span >
</ div >
2026-01-20 17:59:34 +01:00
</ div >
< div class = "ralph-tasks-grid" id = "ralphTasksGrid" ></ div >
2026-01-19 17:09:56 +01:00
</ div >
</ div >
</ div >
2026-01-19 13:21:01 +01:00
</ div >
2026-01-19 00:38:11 +01:00
<!-- Main Terminal Area -->
2026-01-18 05:14:34 +01:00
< main class = "main" >
2026-01-19 00:38:11 +01:00
< div class = "terminal-container" id = "terminalContainer" ></ div >
2026-01-18 05:14:34 +01:00
</ main >
2026-01-19 00:38:11 +01:00
<!-- Bottom Toolbar -->
< footer class = "toolbar" >
< div class = "toolbar-left" >
2026-01-19 01:26:38 +01:00
<!-- Run Claude -->
2026-01-19 00:38:11 +01:00
< div class = "toolbar-group" >
2026-01-19 10:36:30 +01:00
< button class = "btn-toolbar btn-claude" onclick = "app.runClaude()" title = "Run Claude (Ctrl+Enter)" >
2026-01-19 01:26:38 +01:00
Run Claude
</ button >
2026-01-21 13:16:13 +01:00
< div class = "tab-count-group" title = "Instance count" >
< button class = "tab-count-btn" onclick = "app.decrementTabCount()" title = "Instance count" > − </ button >
< input type = "number" id = "tabCount" class = "tab-count-input" value = "1" min = "1" max = "20" readonly title = "Instance count" >
< button class = "tab-count-btn" onclick = "app.incrementTabCount()" title = "Instance count" > +</ button >
2026-01-19 03:40:57 +01:00
</ div >
2026-01-19 10:36:30 +01:00
< button class = "btn-toolbar btn-shell" onclick = "app.runShell()" title = "Run Shell" >
Run Shell
2026-01-19 00:38:11 +01:00
</ button >
2026-01-21 13:16:13 +01:00
< div class = "tab-count-group" title = "Instance count" >
< button class = "tab-count-btn" onclick = "app.decrementShellCount()" title = "Instance count" > − </ button >
< input type = "number" id = "shellCount" class = "tab-count-input" value = "1" min = "1" max = "20" readonly title = "Instance count" >
< button class = "tab-count-btn" onclick = "app.incrementShellCount()" title = "Instance count" > +</ button >
</ div >
2026-01-19 10:36:30 +01:00
< div class = "case-select-group" >
< select id = "quickStartCase" class = "toolbar-select" title = "Select case" >
< option value = "testcase" > testcase</ option >
</ select >
< button class = "btn-case-add" onclick = "app.showCreateCaseModal()" title = "Create new case" > +</ button >
</ div >
2026-01-18 21:36:37 +01:00
</ div >
2026-01-18 07:31:19 +01:00
2026-01-25 09:11:48 +01:00
<!-- Directory (hidden) -->
< div class = "toolbar-group" style = "display: none;" >
2026-01-19 00:38:11 +01:00
< button class = "btn-toolbar" onclick = "app.toggleDirInput()" title = "Set working directory" >
< span id = "dirDisplay" > No directory</ span >
</ button >
< input type = "text" id = "dirInput" class = "toolbar-input hidden" placeholder = "Working directory..." onblur = "app.hideDirInput()" >
2026-01-18 07:31:19 +01:00
</ div >
2026-01-19 00:38:11 +01:00
</ div >
2026-01-25 04:04:24 +01:00
< div class = "toolbar-center" >
< span class = "version-display" id = "versionDisplay" title = "Claudeman version" > v0.0.0</ span >
</ div >
2026-01-19 00:38:11 +01:00
< div class = "toolbar-right" >
</ div >
</ footer >
2026-01-18 22:18:17 +01:00
<!-- Help Modal -->
< div class = "modal" id = "helpModal" >
< div class = "modal-backdrop" onclick = "app.closeHelp()" ></ div >
< div class = "modal-content" >
< div class = "modal-header" >
< h3 > Keyboard Shortcuts</ h3 >
< button class = "modal-close" onclick = "app.closeHelp()" > × </ button >
</ div >
< div class = "modal-body" >
2026-01-19 00:38:11 +01:00
< div class = "shortcuts-grid" >
2026-01-19 01:42:47 +01:00
< div >< kbd > Ctrl</ kbd > +< kbd > Enter</ kbd ></ div >< div > Run Claude</ div >
2026-01-19 00:38:11 +01:00
< div >< kbd > Ctrl</ kbd > +< kbd > W</ kbd ></ div >< div > Close Session</ div >
< div >< kbd > Ctrl</ kbd > +< kbd > Tab</ kbd ></ div >< div > Next Session</ div >
2026-01-19 10:36:30 +01:00
< div >< kbd > Ctrl</ kbd > +< kbd > K</ kbd ></ div >< div > Kill All Sessions + Screens</ div >
2026-01-19 00:38:11 +01:00
< div >< kbd > Ctrl</ kbd > +< kbd > L</ kbd ></ div >< div > Clear Terminal</ div >
< div >< kbd > Ctrl</ kbd > +< kbd > +</ kbd ></ div >< div > Increase Font</ div >
< div >< kbd > Ctrl</ kbd > +< kbd > -</ kbd ></ div >< div > Decrease Font</ div >
< div >< kbd > Ctrl</ kbd > +< kbd > ?</ kbd ></ div >< div > Show Help</ div >
< div >< kbd > Escape</ kbd ></ div >< div > Close Panels</ div >
2026-01-18 22:18:17 +01:00
</ div >
</ div >
</ div >
</ div >
2026-01-19 00:38:11 +01:00
2026-01-25 18:11:14 +01:00
<!-- Monitor Panel (Screen Sessions + Background Tasks) -->
2026-01-19 02:48:28 +01:00
< div class = "monitor-panel" id = "monitorPanel" >
2026-01-19 10:36:30 +01:00
< div class = "monitor-panel-header" id = "monitorPanelHeader" >
2026-01-25 18:11:14 +01:00
< div class = "monitor-panel-title" > Monitor</ div >
2026-01-19 02:48:28 +01:00
< div class = "monitor-panel-actions" >
2026-01-19 11:37:16 +01:00
< button class = "btn-toolbar btn-sm btn-danger" onclick = "app.killAllSessions()" title = "Kill all sessions and their screen processes" > Kill All</ button >
2026-01-19 04:22:41 +01:00
< button class = "btn-icon-sm" onclick = "app.reconcileScreens()" title = "Refresh screens" > ↻ </ button >
2026-01-19 19:28:46 +01:00
< button class = "btn-icon-sm" onclick = "app.toggleMonitorDetach()" title = "Detach panel" id = "monitorDetachBtn" > ⧉ </ button >
< button class = "btn-icon-sm" onclick = "app.toggleMonitorPanel()" title = "Toggle panel" id = "monitorToggleBtn" > ▲ </ button >
2026-01-20 17:54:59 +01:00
< button class = "btn-icon-sm" onclick = "app.closeMonitor()" title = "Close monitor" > × </ button >
2026-01-19 02:18:51 +01:00
</ div >
</ div >
2026-01-19 10:36:30 +01:00
< div class = "monitor-resize-handle" id = "monitorResizeHandle" ></ div >
2026-01-25 18:11:14 +01:00
< div class = "monitor-panel-body" id = "monitorTabContent" >
2026-01-19 02:48:28 +01:00
< div class = "monitor-section" >
< div class = "monitor-section-header" >
< span > Screen Sessions</ span >
</ div >
< div class = "monitor-section-body" id = "screenSessionsBody" >
< div class = "monitor-empty" > No screen sessions</ div >
</ div >
</ div >
2026-01-19 04:02:46 +01:00
< div class = "monitor-section" id = "backgroundTasksSection" style = "display: none;" >
2026-01-19 02:48:28 +01:00
< div class = "monitor-section-header" >
< span > Background Tasks</ span >
< span class = "task-stats" id = "taskPanelStats" > 0 running</ span >
</ div >
< div class = "monitor-section-body" id = "backgroundTasksBody" >
</ div >
</ div >
2026-01-25 17:40:28 +01:00
</ div >
2026-01-25 18:11:14 +01:00
</ div >
<!-- Subagents Panel (separate from Monitor) -->
< div class = "subagents-panel" id = "subagentsPanel" >
2026-01-25 18:33:43 +01:00
< div class = "subagents-panel-header" id = "subagentsPanelHeader" >
2026-01-25 18:11:14 +01:00
< div class = "subagents-panel-title" >
Subagents < span id = "subagentCountBadge" class = "subagent-badge" ></ span >
</ div >
< div class = "subagents-panel-actions" >
2026-01-25 18:33:43 +01:00
< button class = "btn-icon-sm" onclick = "app.toggleSubagentsDetach()" title = "Detach panel" id = "subagentsDetachBtn" > ⧉ </ button >
2026-01-25 18:11:14 +01:00
< button class = "btn-icon-sm" onclick = "app.toggleSubagentsPanel()" title = "Toggle panel" id = "subagentsToggleBtn" > ▲ </ button >
< button class = "btn-icon-sm" onclick = "app.closeSubagentsPanel()" title = "Close" > × </ button >
</ div >
</ div >
2026-01-25 18:33:43 +01:00
< div class = "subagents-resize-handle" id = "subagentsResizeHandle" ></ div >
2026-01-25 18:11:14 +01:00
< div class = "subagents-panel-body" id = "subagentsTabContent" >
2026-01-25 17:40:28 +01:00
< div class = "subagent-container" >
< div class = "subagent-list" id = "subagentList" >
< div class = "subagent-empty" > No background agents detected</ div >
2026-01-25 14:33:12 +01:00
</ div >
2026-01-25 17:40:28 +01:00
< div class = "subagent-detail" id = "subagentDetail" >
< div class = "subagent-empty" > Select an agent to view details</ div >
2026-01-25 14:33:12 +01:00
</ div >
</ div >
2026-01-19 00:38:11 +01:00
</ div >
</ div >
2026-01-19 03:40:57 +01:00
<!-- Session Options Modal (includes Respawn Settings) -->
2026-01-19 01:26:38 +01:00
< div class = "modal" id = "sessionOptionsModal" >
< div class = "modal-backdrop" onclick = "app.closeSessionOptions()" ></ div >
2026-01-19 03:40:57 +01:00
< div class = "modal-content" >
2026-01-19 01:26:38 +01:00
< div class = "modal-header" >
< h3 > Session Options</ h3 >
< button class = "modal-close" onclick = "app.closeSessionOptions()" > × </ button >
</ div >
2026-01-19 18:25:31 +01:00
<!-- Modal Tabs -->
< div class = "modal-tabs" >
< button class = "modal-tab-btn active" data-tab = "respawn" onclick = "app.switchOptionsTab('respawn')" > Respawn</ button >
2026-01-24 19:12:47 +01:00
< button class = "modal-tab-btn" data-tab = "context" onclick = "app.switchOptionsTab('context')" > Context</ button >
< button class = "modal-tab-btn" data-tab = "ralph" onclick = "app.switchOptionsTab('ralph')" > Ralph / Todo</ button >
2026-01-19 18:25:31 +01:00
</ div >
2026-01-19 01:26:38 +01:00
< div class = "modal-body" >
2026-01-19 18:25:31 +01:00
<!-- Respawn Tab Content -->
< div class = "modal-tab-content" id = "respawn-tab" >
2026-01-19 03:40:57 +01:00
<!-- Respawn Settings Section -->
< div class = "session-respawn-section" id = "sessionRespawnSection" >
< div class = "section-divider" >
< div class = "session-respawn-status" id = "sessionRespawnStatus" >
< span class = "respawn-status-indicator" ></ span >
< span class = "respawn-status-text" > Not active</ span >
</ div >
2026-01-19 02:06:37 +01:00
</ div >
2026-01-19 03:40:57 +01:00
2026-01-19 14:37:20 +01:00
< div class = "form-row" >
< label > Run Duration</ label >
< div class = "duration-presets" >
< button type = "button" class = "duration-preset-btn" data-minutes = "30" onclick = "app.selectDurationPreset('30')" > 30m</ button >
< button type = "button" class = "duration-preset-btn" data-minutes = "60" onclick = "app.selectDurationPreset('60')" > 1h</ button >
< button type = "button" class = "duration-preset-btn" data-minutes = "120" onclick = "app.selectDurationPreset('120')" > 2h</ button >
< button type = "button" class = "duration-preset-btn" data-minutes = "240" onclick = "app.selectDurationPreset('240')" > 4h</ button >
< button type = "button" class = "duration-preset-btn" data-minutes = "480" onclick = "app.selectDurationPreset('480')" > 8h</ button >
< button type = "button" class = "duration-preset-btn active" data-minutes = "" onclick = "app.selectDurationPreset('')" > ∞</ button >
< div class = "duration-custom" >
< button type = "button" class = "duration-preset-btn" data-minutes = "custom" onclick = "app.selectDurationPreset('custom')" > Custom</ button >
< div class = "input-suffix input-suffix-sm duration-custom-input" >
< input type = "number" id = "modalRespawnDuration" value = "" min = "1" placeholder = "min" >
< span > min</ span >
</ div >
</ div >
</ div >
< span class = "form-hint" > How long to run the respawn loop</ span >
</ div >
2026-01-19 03:40:57 +01:00
< div class = "form-row" >
< label > Update Prompt</ label >
2026-01-22 20:49:09 +01:00
< input type = "text" id = "modalRespawnPrompt" value = "update all the docs and CLAUDE.md" placeholder = "Prompt to send when idle" onchange = "app.autoSaveRespawnConfig()" >
2026-01-19 03:40:57 +01:00
</ div >
< div class = "form-row" >
< label > After Update Prompt</ label >
< div class = "checkbox-group-inline" >
< label class = "checkbox-inline" >
2026-01-22 20:49:09 +01:00
< input type = "checkbox" id = "modalRespawnSendClear" checked onchange = "app.autoSaveRespawnConfig()" >
2026-01-19 03:40:57 +01:00
< span > Send /clear</ span >
</ label >
< label class = "checkbox-inline" >
2026-01-22 20:49:09 +01:00
< input type = "checkbox" id = "modalRespawnSendInit" checked onchange = "app.autoSaveRespawnConfig()" >
2026-01-19 03:40:57 +01:00
< span > Send /init</ span >
</ label >
</ div >
</ div >
2026-01-19 13:08:53 +01:00
< div class = "form-row" >
< label > Kickstart Prompt</ label >
2026-01-22 20:49:09 +01:00
< input type = "text" id = "modalRespawnKickstart" value = "" placeholder = "Optional: prompt if /init doesn't trigger work" onchange = "app.autoSaveRespawnConfig()" >
2026-01-19 13:08:53 +01:00
< span class = "form-hint" > Sent only when /init completes but Claude stays idle</ span >
</ div >
2026-01-23 01:25:09 +01:00
< div class = "form-row" >
2026-01-24 03:10:02 +01:00
< label > Auto-Accept Plan Mode</ label >
2026-01-23 01:25:09 +01:00
< div class = "checkbox-group-inline" >
< label class = "checkbox-inline" >
< input type = "checkbox" id = "modalRespawnAutoAccept" checked onchange = "app.autoSaveRespawnConfig()" >
2026-01-24 03:10:02 +01:00
< span > Accept plan mode approvals</ span >
2026-01-23 01:25:09 +01:00
</ label >
</ div >
< span class = "form-hint" > Presses Enter to accept plan approvals and default question options when Claude is waiting</ span >
</ div >
2026-01-24 19:12:47 +01:00
< div class = "respawn-actions" >
< button class = "btn-toolbar btn-success" onclick = "app.enableRespawnFromModal()" id = "modalEnableRespawnBtn" > Enable Respawn</ button >
< button class = "btn-toolbar btn-danger" onclick = "app.stopRespawnFromModal()" id = "modalStopRespawnBtn" style = "display: none;" > Stop Respawn</ button >
</ div >
</ div >
</ div > <!-- End respawn-tab -->
<!-- Context Management Tab Content -->
< div class = "modal-tab-content hidden" id = "context-tab" >
2026-01-19 13:08:53 +01:00
< div class = "form-row" >
< label > Auto-Compact Context</ label >
< div class = "auto-clear-row" >
< label class = "checkbox-inline" >
2026-01-22 20:49:09 +01:00
< input type = "checkbox" id = "modalAutoCompactEnabled" onchange = "app.autoSaveAutoCompact()" >
2026-01-19 13:08:53 +01:00
< span > Enable at</ span >
</ label >
< div class = "input-suffix input-suffix-sm" >
2026-01-22 20:49:09 +01:00
< input type = "number" id = "modalAutoCompactThreshold" value = "110000" min = "10000" max = "500000" step = "10000" onchange = "app.autoSaveAutoCompact()" >
2026-01-19 13:08:53 +01:00
< span > tokens</ span >
</ div >
</ div >
2026-01-22 20:49:09 +01:00
< input type = "text" id = "modalAutoCompactPrompt" value = "" placeholder = "Optional: focus prompt for compact" class = "mt-sm" onchange = "app.autoSaveAutoCompact()" >
2026-01-19 13:08:53 +01:00
< span class = "form-hint" > Summarizes context while preserving key information</ span >
</ div >
2026-01-19 03:40:57 +01:00
< div class = "form-row" >
< label > Auto-Clear Context</ label >
< div class = "auto-clear-row" >
< label class = "checkbox-inline" >
2026-01-22 20:49:09 +01:00
< input type = "checkbox" id = "modalAutoClearEnabled" onchange = "app.autoSaveAutoClear()" >
2026-01-19 03:40:57 +01:00
< span > Enable at</ span >
</ label >
< div class = "input-suffix input-suffix-sm" >
2026-01-22 20:49:09 +01:00
< input type = "number" id = "modalAutoClearThreshold" value = "140000" min = "10000" max = "500000" step = "10000" onchange = "app.autoSaveAutoClear()" >
2026-01-19 03:40:57 +01:00
< span > tokens</ span >
</ div >
</ div >
2026-01-19 13:08:53 +01:00
< span class = "form-hint" > Completely resets context (use higher threshold than compact)</ span >
2026-01-19 03:40:57 +01:00
</ div >
2026-01-24 19:12:47 +01:00
</ div > <!-- End context-tab -->
2026-01-19 18:25:31 +01:00
<!-- Ralph Wiggum Tab Content -->
< div class = "modal-tab-content hidden" id = "ralph-tab" >
2026-01-19 18:56:34 +01:00
< div class = "form-row form-row-switch" >
< label > Enable Tracker</ label >
< label class = "switch" >
< input type = "checkbox" id = "modalRalphEnabled" >
< span class = "slider" ></ span >
</ label >
2026-01-21 22:36:45 +01:00
< span class = "form-hint" > Enable Ralph / Todo tracker for this session (auto-detects loops and todos)</ span >
2026-01-19 18:56:34 +01:00
</ div >
2026-01-19 18:25:31 +01:00
< div class = "form-row" >
< label > Completion Phrase</ label >
< input type = "text" id = "modalRalphPhrase" placeholder = "e.g., COMPLETE, DONE, FINISHED" >
< span class = "form-hint" > The phrase Claude outputs when the loop is complete (without < promise> tags)</ span >
</ div >
< div class = "form-row" >
< label > Max Iterations</ label >
< input type = "number" id = "modalRalphMaxIterations" value = "0" min = "0" max = "1000" >
< span class = "form-hint" > Maximum respawn cycles (0 = unlimited)</ span >
</ div >
< div class = "form-row" >
< label > Max Todos</ label >
< input type = "number" id = "modalRalphMaxTodos" value = "50" min = "1" max = "500" >
< span class = "form-hint" > Maximum todos to track per session</ span >
</ div >
< div class = "form-row" >
< label > Todo Expiration</ label >
< div class = "input-suffix input-suffix-sm" >
< input type = "number" id = "modalRalphTodoExpiration" value = "60" min = "1" max = "1440" >
< span > min</ span >
</ div >
< span class = "form-hint" > Minutes before todos auto-expire</ span >
</ div >
< div class = "ralph-config-actions" >
< button class = "btn-toolbar btn-primary" onclick = "app.saveRalphConfig()" > Save Ralph Config</ button >
</ div >
</ div > <!-- End ralph-tab -->
2026-01-19 01:26:38 +01:00
</ div >
</ div >
</ div >
2026-01-19 02:10:44 +01:00
<!-- Close Session Confirmation Modal -->
< div class = "modal" id = "closeConfirmModal" >
< div class = "modal-backdrop" onclick = "app.cancelCloseSession()" ></ div >
< div class = "modal-content modal-sm" >
< div class = "modal-header" >
2026-01-19 04:55:51 +01:00
< h3 > Close Session</ h3 >
2026-01-19 02:10:44 +01:00
< button class = "modal-close" onclick = "app.cancelCloseSession()" > × </ button >
</ div >
< div class = "modal-body" >
< p class = "modal-session-name" id = "closeConfirmSessionName" ></ p >
</ div >
2026-01-19 04:55:51 +01:00
< div class = "close-options" >
< button class = "close-option" onclick = "app.confirmCloseSession(false)" >
< span class = "close-option-title" > Remove Tab</ span >
< span class = "close-option-desc" > Screen session keeps running in background</ span >
</ button >
< button class = "close-option close-option-danger" onclick = "app.confirmCloseSession(true)" >
< span class = "close-option-title" > Kill Claude</ span >
< span class = "close-option-desc" > Terminate the session completely</ span >
</ button >
</ div >
< div class = "modal-footer-cancel" >
< button class = "btn-toolbar btn-sm" onclick = "app.cancelCloseSession()" > Cancel</ button >
2026-01-19 02:10:44 +01:00
</ div >
</ div >
</ div >
2026-01-19 02:08:58 +01:00
<!-- App Settings Modal -->
< div class = "modal" id = "appSettingsModal" >
< div class = "modal-backdrop" onclick = "app.closeAppSettings()" ></ div >
2026-01-21 13:07:45 +01:00
< div class = "modal-content modal-lg" >
2026-01-19 02:08:58 +01:00
< div class = "modal-header" >
< h3 > App Settings</ h3 >
< button class = "modal-close" onclick = "app.closeAppSettings()" > × </ button >
</ div >
2026-01-21 13:07:45 +01:00
< div class = "modal-tabs" >
< button class = "modal-tab-btn active" data-tab = "settings-display" > Display</ button >
< button class = "modal-tab-btn" data-tab = "settings-claude" > Claude CLI</ button >
< button class = "modal-tab-btn" data-tab = "settings-paths" > Paths</ button >
2026-01-24 01:22:53 +01:00
< button class = "modal-tab-btn" data-tab = "settings-notifications" > Notifications</ button >
2026-01-21 13:07:45 +01:00
</ div >
2026-01-19 02:08:58 +01:00
< div class = "modal-body" >
2026-01-21 13:07:45 +01:00
<!-- Display Tab -->
< div class = "modal-tab-content" id = "settings-display" >
2026-01-19 19:22:28 +01:00
< div class = "form-row form-row-switch" >
< label > Show Font Controls</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsShowFontControls" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Show A-/A+ font size buttons in header</ span >
</ div >
< div class = "form-row form-row-switch" >
< label > Show System Stats</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsShowSystemStats" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Show CPU and memory usage in header</ span >
</ div >
< div class = "form-row form-row-switch" >
< label > Show Token Count</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsShowTokenCount" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Show total token count in header</ span >
</ div >
2026-01-20 17:54:59 +01:00
< div class = "form-row form-row-switch" >
< label > Show Monitor Panel</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsShowMonitor" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Show Monitor panel at bottom right</ span >
</ div >
2026-01-25 18:09:25 +01:00
< div class = "form-row form-row-switch" >
< label > Enable Subagent Tracking</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsSubagentTracking" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Monitor Claude Code background agents in real-time</ span >
</ div >
< div class = "form-row form-row-switch" >
< label > Show Subagents Panel</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsShowSubagents" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Show the Subagents panel (independent from Monitor)</ span >
</ div >
2026-01-19 02:08:58 +01:00
</ div >
2026-01-21 13:07:45 +01:00
<!-- Claude CLI Tab -->
< div class = "modal-tab-content hidden" id = "settings-claude" >
2026-01-21 04:19:34 +01:00
< div class = "form-row" >
< label > Startup Mode</ label >
< select id = "appSettingsClaudeMode" class = "form-select" >
< option value = "dangerously-skip-permissions" > Skip Permissions (default)</ option >
< option value = "normal" > Normal (with prompts)</ option >
< option value = "allowedTools" > Allowed Tools Only</ option >
</ select >
< span class = "form-hint" > How Claude CLI is started in screen sessions</ span >
</ div >
< div class = "form-row" id = "allowedToolsRow" style = "display: none;" >
< label > Allowed Tools</ label >
< input type = "text" id = "appSettingsAllowedTools" placeholder = "Read,Glob,Grep,Bash" >
2026-01-21 13:07:45 +01:00
< span class = "form-hint" > Comma-separated list of tools to allow</ span >
</ div >
< div class = "form-row form-row-switch" >
2026-01-21 22:36:45 +01:00
< label > Enable Ralph / Todo Tracker</ label >
2026-01-21 13:07:45 +01:00
< label class = "switch" >
< input type = "checkbox" id = "appSettingsRalphEnabled" >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Auto-enable for new sessions (otherwise auto-enables on Ralph pattern detection)</ span >
2026-01-21 04:19:34 +01:00
</ div >
</ div >
2026-01-21 13:07:45 +01:00
<!-- Paths Tab -->
< div class = "modal-tab-content hidden" id = "settings-paths" >
2026-01-19 19:22:28 +01:00
< div class = "form-row" >
2026-01-21 13:07:45 +01:00
< label > Default CLAUDE.md Template</ label >
2026-01-19 19:22:28 +01:00
< input type = "text" id = "appSettingsClaudeMdPath" placeholder = "/path/to/CLAUDE.md template" >
< span class = "form-hint" > Used when creating new cases. Leave empty for built-in template.</ span >
</ div >
< div class = "form-row" >
< label > Default Working Directory</ label >
< input type = "text" id = "appSettingsDefaultDir" placeholder = "~/projects" >
< span class = "form-hint" > Default directory for new sessions.</ span >
</ div >
2026-01-21 04:19:34 +01:00
</ div >
2026-01-24 01:22:53 +01:00
<!-- Notifications Tab -->
< div class = "modal-tab-content hidden" id = "settings-notifications" >
< div class = "form-row form-row-switch" >
< label > Enable Notifications</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsNotifEnabled" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Master toggle for all notification layers</ span >
</ div >
< div class = "form-row form-row-switch" >
< label > Browser Notifications</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsNotifBrowser" >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Show OS-level notifications when tab is hidden</ span >
</ div >
< div class = "form-row" >
< button class = "btn-toolbar btn-sm" onclick = "app.notificationManager?.requestPermission()" > Request Permission</ button >
< span class = "form-hint" id = "notifPermissionStatus" > Status: unknown</ span >
</ div >
< div class = "form-row form-row-switch" >
< label > Audio Alerts</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsNotifAudio" >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Play a short beep for critical events</ span >
</ div >
< div class = "form-row" >
< label > Idle Threshold (minutes)</ label >
< input type = "number" id = "appSettingsNotifStuckMins" value = "10" min = "1" max = "120" style = "width: 80px;" >
< span class = "form-hint" > Notify when a session is idle longer than this</ span >
</ div >
< div class = "form-row form-row-switch" >
< label > Critical Notifications</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsNotifCritical" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Errors, crashes, agent failures</ span >
</ div >
< div class = "form-row form-row-switch" >
< label > Warning Notifications</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsNotifWarning" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Completions, budget warnings, stuck sessions</ span >
</ div >
< div class = "form-row form-row-switch" >
< label > Info Notifications</ label >
< label class = "switch" >
< input type = "checkbox" id = "appSettingsNotifInfo" checked >
< span class = "slider" ></ span >
</ label >
< span class = "form-hint" > Auto-accepts, auto-clears, agent completions</ span >
</ div >
</ div >
2026-01-19 02:08:58 +01:00
</ div >
< div class = "form-actions" >
< button class = "btn-toolbar" onclick = "app.closeAppSettings()" > Cancel</ button >
< button class = "btn-toolbar btn-primary" onclick = "app.saveAppSettings()" > Save</ button >
</ div >
</ div >
</ div >
2026-01-19 10:36:30 +01:00
<!-- Create Case Modal -->
< div class = "modal" id = "createCaseModal" >
< div class = "modal-backdrop" onclick = "app.closeCreateCaseModal()" ></ div >
2026-01-21 13:20:43 +01:00
< div class = "modal-content modal-lg" >
2026-01-19 10:36:30 +01:00
< div class = "modal-header" >
2026-01-21 13:20:43 +01:00
< h3 > Add Case</ h3 >
2026-01-19 10:36:30 +01:00
< button class = "modal-close" onclick = "app.closeCreateCaseModal()" > × </ button >
</ div >
2026-01-21 13:20:43 +01:00
< div class = "modal-tabs" >
< button class = "modal-tab-btn active" data-tab = "case-create" > Create New</ button >
< button class = "modal-tab-btn" data-tab = "case-link" > Link Existing</ button >
</ div >
2026-01-19 10:36:30 +01:00
< div class = "modal-body" >
2026-01-21 13:20:43 +01:00
<!-- Create New Tab -->
< div class = "modal-tab-content" id = "case-create" >
< div class = "form-row" >
< label > Case Name</ label >
< input type = "text" id = "newCaseName" placeholder = "my-project" pattern = "[a-zA-Z0-9_-]+" >
< span class = "form-hint" > Letters, numbers, hyphens, underscores only. Created in ~/claudeman-cases/</ span >
</ div >
< div class = "form-row" >
< label > Description (optional)</ label >
< input type = "text" id = "newCaseDescription" placeholder = "A brief description..." >
</ div >
2026-01-19 10:36:30 +01:00
</ div >
2026-01-21 13:20:43 +01:00
<!-- Link Existing Tab -->
< div class = "modal-tab-content hidden" id = "case-link" >
< div class = "form-row" >
< label > Case Name</ label >
< input type = "text" id = "linkCaseName" placeholder = "my-project" pattern = "[a-zA-Z0-9_-]+" >
< span class = "form-hint" > Name to identify this case in Claudeman</ span >
</ div >
< div class = "form-row" >
< label > Folder Path</ label >
< input type = "text" id = "linkCasePath" placeholder = "/home/user/projects/my-project" >
< span class = "form-hint" > Absolute path to an existing project folder</ span >
</ div >
2026-01-19 10:36:30 +01:00
</ div >
</ div >
< div class = "form-actions" >
< button class = "btn-toolbar" onclick = "app.closeCreateCaseModal()" > Cancel</ button >
2026-01-21 13:20:43 +01:00
< button class = "btn-toolbar btn-primary" id = "caseModalSubmit" onclick = "app.submitCaseModal()" > Create</ button >
2026-01-19 10:36:30 +01:00
</ div >
</ div >
</ div >
<!-- Kill All Confirmation Modal -->
< div class = "modal" id = "killAllModal" >
< div class = "modal-backdrop" onclick = "app.closeKillAllModal()" ></ div >
< div class = "modal-content modal-sm" >
< div class = "modal-header" >
< h3 > Kill All Sessions</ h3 >
< button class = "modal-close" onclick = "app.closeKillAllModal()" > × </ button >
</ div >
< div class = "modal-body" >
< p class = "modal-warning-text" > Choose how to close < span id = "killAllCount" > 0</ span > session(s):</ p >
</ div >
< div class = "close-options" >
< button class = "close-option" onclick = "app.confirmKillAll(false)" >
< span class = "close-option-title" > Remove All Tabs</ span >
< span class = "close-option-desc" > Screen sessions keep running in background</ span >
</ button >
< button class = "close-option close-option-danger" onclick = "app.confirmKillAll(true)" >
< span class = "close-option-title" > Kill All Claude + Screens</ span >
< span class = "close-option-desc" > Terminate everything completely</ span >
</ button >
</ div >
< div class = "modal-footer-cancel" >
< button class = "btn-toolbar btn-sm" onclick = "app.closeKillAllModal()" > Cancel</ button >
</ div >
</ div >
</ div >
2026-01-24 01:22:53 +01:00
<!-- Notification Drawer -->
< div class = "notification-drawer" id = "notifDrawer" >
< div class = "notif-drawer-header" >
< span class = "notif-drawer-title" > Notifications</ span >
< div class = "notif-drawer-actions" >
< button class = "btn-notif-action" onclick = "app.notificationManager?.markAllRead()" title = "Mark all read" > ✓ </ button >
< button class = "btn-notif-action" onclick = "app.notificationManager?.clearAll()" title = "Clear all" > 🗑 </ button >
< button class = "btn-notif-action" onclick = "app.toggleNotifications()" title = "Close" > × </ button >
</ div >
</ div >
< div class = "notif-drawer-list" id = "notifList" ></ div >
< div class = "notif-drawer-empty" id = "notifEmpty" > No notifications</ div >
</ div >
2026-01-19 00:38:11 +01:00
<!-- Help Button -->
< button class = "help-btn" onclick = "app.showHelp()" title = "Keyboard shortcuts (Ctrl+?)" > ?</ button >
2026-01-25 20:36:04 +01:00
<!-- Token Stats Modal -->
< div class = "modal" id = "tokenStatsModal" >
< div class = "modal-backdrop" onclick = "app.closeTokenStats()" ></ div >
< div class = "modal-content token-stats-modal" >
< div class = "modal-header" >
< h3 > Token Usage Statistics</ h3 >
< button class = "modal-close" onclick = "app.closeTokenStats()" > × </ button >
</ div >
< div class = "modal-body" >
< div class = "stats-summary" id = "statsSummary" ></ div >
< div class = "stats-chart-container" >
< div class = "stats-chart-label" > Last 7 Days</ div >
< div class = "stats-chart" id = "statsChart" ></ div >
< div class = "stats-chart-days" id = "statsChartDays" ></ div >
</ div >
< div class = "stats-table-container" >
< div class = "stats-table-label" > Daily Breakdown</ div >
< div class = "stats-table" id = "statsTable" ></ div >
</ div >
</ div >
</ div >
</ div >
2026-01-18 05:14:34 +01:00
</ div >
< script src = "app.js" ></ script >
</ body >
</ html >