feat: implement 13 features — auto-reconnect, notifications, bulk actions, latency, traffic, theme, export/import, scheduled backups, peer lookup, SSH auto-reconnect, log filters, keyboard shortcut, and readyTimeout default
CI / Build & Test (push) Successful in 2m44s

- Change readyTimeoutMs default from 0 to 30000 in both state files
- Register Alt+Shift+H keyboard shortcut via manifest _execute_action command
- Add severity filter buttons (All/Info/Warn/Error) and Download .txt to Logs page; background logs.js now tags entries with proper level field
- Fire browser notifications on tunnelError events (notifyOnTunnelError setting)
- Add exponential-backoff auto-reconnect for virtual hosts and service tunnels (tunnelAutoReconnect setting, 5s–120s backoff)
- Add backupIntervalHours setting and scheduled auto-backup timer in message-router.js
- Add TCP connect latency badges to Virtual Hosts and Service Tunnels tables via new pingTunnel native message
- Add bytesIn/bytesOut/requests counters to https-proxy.js; expose in Overview status bar via getState
- Add Export/Import connection configs (JSON, no CA key) in Settings
- Add autoReconnect flag and exponential-backoff reconnect to SSH connection cards
- Add light theme CSS variables and theme toggle in Settings (persisted to localStorage)
- Add checkbox column and bulk Stop/Remove actions to Virtual Hosts, Service Tunnels, and Servers tables
- Add Peer Lookup UI card on Overview page using existing lookup message handler
This commit is contained in:
Raven Scott
2026-02-28 23:51:14 -05:00
parent 31f30b2974
commit 849897f324
24 changed files with 726 additions and 47 deletions
+8
View File
@@ -2,23 +2,31 @@
function updateSettingsUI() {
$('toggleNotify')?.classList.toggle('active', settings.notifyOnDisconnect === true);
$('toggleNotifyTunnelError')?.classList.toggle('active', settings.notifyOnTunnelError !== false);
$('toggleTunnelAutoReconnect')?.classList.toggle('active', settings.tunnelAutoReconnect === true);
$('toggleDebug')?.classList.toggle('active', settings.debug === true);
$('toggleDisableFileUrls')?.classList.toggle('active', settings.disableOnFileUrls === true);
$('toggleTheme')?.classList.toggle('active', document.documentElement.getAttribute('data-theme') === 'light');
const proxyPortEl = $('proxyPort');
const readyTimeoutMsEl = $('readyTimeoutMs');
const backupRetentionEl = $('backupRetention');
const backupIntervalEl = $('backupIntervalHours');
if (proxyPortEl) proxyPortEl.value = settings.proxyPort ?? SETTINGS_DEFAULTS.proxyPort;
if (readyTimeoutMsEl) readyTimeoutMsEl.value = settings.readyTimeoutMs ?? SETTINGS_DEFAULTS.readyTimeoutMs;
if (backupRetentionEl) backupRetentionEl.value = settings.backupRetention ?? SETTINGS_DEFAULTS.backupRetention;
if (backupIntervalEl) backupIntervalEl.value = settings.backupIntervalHours ?? SETTINGS_DEFAULTS.backupIntervalHours;
}
function saveSettings() {
settings.notifyOnDisconnect = $('toggleNotify')?.classList.contains('active') ?? SETTINGS_DEFAULTS.notifyOnDisconnect;
settings.notifyOnTunnelError = $('toggleNotifyTunnelError')?.classList.contains('active') ?? SETTINGS_DEFAULTS.notifyOnTunnelError;
settings.tunnelAutoReconnect = $('toggleTunnelAutoReconnect')?.classList.contains('active') ?? SETTINGS_DEFAULTS.tunnelAutoReconnect;
settings.debug = $('toggleDebug')?.classList.contains('active') ?? SETTINGS_DEFAULTS.debug;
settings.disableOnFileUrls = $('toggleDisableFileUrls')?.classList.contains('active') ?? SETTINGS_DEFAULTS.disableOnFileUrls;
settings.proxyPort = parseInt($('proxyPort')?.value, 10) || SETTINGS_DEFAULTS.proxyPort;
settings.readyTimeoutMs = parseInt($('readyTimeoutMs')?.value, 10) || SETTINGS_DEFAULTS.readyTimeoutMs;
settings.backupRetention = Math.max(1, parseInt($('backupRetention')?.value, 10) || SETTINGS_DEFAULTS.backupRetention);
settings.backupIntervalHours = Math.max(0, parseInt($('backupIntervalHours')?.value, 10) || 0);
chrome.runtime.sendMessage(
{ target: 'holesail-native', action: 'send', payload: { type: 'updateSettings', payload: { ...settings } } },
(response) => {