From dce9711f18d39ad9bea6d6b161c1aa4f4aedd3d3 Mon Sep 17 00:00:00 2001 From: Kunal Keshari Pattanaik Date: Fri, 5 Jun 2026 14:13:22 +0530 Subject: [PATCH 1/2] Add active terminal session timer --- ui/app.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ ui/index.html | 1 + ui/style.css | 14 ++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/ui/app.js b/ui/app.js index bf7725b..6174ae2 100644 --- a/ui/app.js +++ b/ui/app.js @@ -70,6 +70,7 @@ let state = { sessionId: null, lastSaveTimestamp: 0, runningScripts: {}, // termId -> { step, total, command, status } + terminalTimerInterval: null, reliabilitySummary: null, reliabilityFailures: null, reliabilityTrends: null, @@ -1035,11 +1036,51 @@ function cleanupRunningScript(termId) { delete state.runningScripts[termId]; if (termId === state.activeTerminalId) { + stopTerminalTimer(); updateRunButton(); updateProgressTrackerUI(); } } +function formatElapsedTime(ms) { + const totalSeconds = Math.max(0, Math.floor(ms / 1000)); + const minutes = String(Math.floor(totalSeconds / 60)).padStart(2, '0'); + const seconds = String(totalSeconds % 60).padStart(2, '0'); + return `${minutes}:${seconds}`; +} + +function updateTerminalTimer() { + const timer = document.getElementById('terminal-session-timer'); + if (!timer) return; + + const running = state.runningScripts[state.activeTerminalId]; + if (!running?.startedAt) { + timer.style.display = 'none'; + timer.textContent = '00:00'; + return; + } + + timer.textContent = formatElapsedTime(Date.now() - running.startedAt); + timer.style.display = 'inline-flex'; +} + +function startTerminalTimer() { + stopTerminalTimer(false); + updateTerminalTimer(); + state.terminalTimerInterval = setInterval(updateTerminalTimer, 1000); +} + +function stopTerminalTimer(reset = true) { + if (state.terminalTimerInterval) { + clearInterval(state.terminalTimerInterval); + state.terminalTimerInterval = null; + } + + if (reset) { + updateTerminalTimer(); + } +} + async function abortScriptRun(termId = state.activeTerminalId) { const running = state.runningScripts[termId]; if (!running) return; @@ -1145,9 +1186,11 @@ async function executeScriptWithArguments(relPath, argumentsText) { total: 0, command: 'Starting script...', status: 'running', + startedAt: Date.now(), controller: controller }; updateRunButton(); + startTerminalTimer(); if (termId === state.activeTerminalId) { runStatus.textContent = 'Executing...'; @@ -2805,9 +2848,11 @@ function switchTerminal(id) { runStatus.textContent = running.aborting ? 'Aborting...' : 'Executing...'; runStatus.className = 'run-status running'; resourcePanel.style.display = 'none'; + startTerminalTimer(); } else { runStatus.textContent = ''; runStatus.className = 'run-status'; + stopTerminalTimer(); } updateRunButton(); highlightTerminalSearch(); diff --git a/ui/index.html b/ui/index.html index 58399eb..9fa238b 100644 --- a/ui/index.html +++ b/ui/index.html @@ -360,6 +360,7 @@

Scripts

+