termites 1.0.38 → 1.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +20 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "termites",
3
- "version": "1.0.38",
3
+ "version": "1.0.39",
4
4
  "description": "Local multi-terminal manager with web interface",
5
5
  "main": "server.js",
6
6
  "scripts": {
package/server.js CHANGED
@@ -771,6 +771,14 @@ class TermitesServer {
771
771
  .close-terminal-btn:hover { opacity: 1; color: #ef4444; }
772
772
  .status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; flex-shrink: 0; }
773
773
  .status-dot.online { background: #22c55e; }
774
+ .unread-badge {
775
+ display: inline-block; width: 8px; height: 8px; border-radius: 50%;
776
+ background: #f59e0b; margin-left: 6px; animation: pulse 1.5s infinite;
777
+ }
778
+ @keyframes pulse {
779
+ 0%, 100% { opacity: 1; }
780
+ 50% { opacity: 0.5; }
781
+ }
774
782
  .settings-section { padding: 12px 16px; }
775
783
  .setting-group { margin-bottom: 16px; }
776
784
  .setting-group:last-child { margin-bottom: 0; }
@@ -981,6 +989,7 @@ class TermitesServer {
981
989
  let ws, term, fitAddon;
982
990
  let clients = [];
983
991
  let selectedClientId = null;
992
+ let unreadTerminals = new Set(); // Track terminals with unread output
984
993
  // History buffer for iTerm-like scrolling (stores raw output)
985
994
  let historyBuffer = [];
986
995
  const MAX_HISTORY_SIZE = 100000; // Max characters to store
@@ -1702,12 +1711,14 @@ class TermitesServer {
1702
1711
  }
1703
1712
  listEl.innerHTML = clients.map(c => {
1704
1713
  const isSelected = c.id === selectedClientId;
1714
+ const hasUnread = unreadTerminals.has(c.id);
1705
1715
  const bgColor = isSelected ? t.sidebarSelected : 'transparent';
1706
1716
  return '<div class="client-item' + (isSelected ? ' selected' : '') + '" ' +
1707
1717
  'style="background: ' + bgColor + ';">' +
1708
1718
  '<div class="client-main" onclick="selectClient(\\'' + c.id + '\\')">' +
1709
1719
  '<div class="client-name"><span class="status-dot online"></span>' +
1710
- c.username + '@' + c.hostname + '</div>' +
1720
+ c.username + '@' + c.hostname +
1721
+ (hasUnread ? '<span class="unread-badge"></span>' : '') + '</div>' +
1711
1722
  '<div class="client-info">' + (c.cwd || '') + ' · ' + (c.platform || '') + '</div></div>' +
1712
1723
  '<button class="close-terminal-btn" onclick="event.stopPropagation(); closeTerminal(\\'' + c.id + '\\')" title="Close terminal">×</button></div>';
1713
1724
  }).join('');
@@ -1728,6 +1739,8 @@ class TermitesServer {
1728
1739
  return;
1729
1740
  }
1730
1741
  selectedClientId = clientId;
1742
+ // Clear unread badge for this terminal
1743
+ unreadTerminals.delete(clientId);
1731
1744
  const client = clients.find(c => c.id === clientId);
1732
1745
  if (client) {
1733
1746
  document.getElementById('header-title').innerHTML =
@@ -1905,6 +1918,12 @@ class TermitesServer {
1905
1918
  addToHistory(d.data);
1906
1919
  term.write(d.data);
1907
1920
  term.scrollToBottom();
1921
+ } else {
1922
+ // Mark terminal as having unread output
1923
+ if (!unreadTerminals.has(d.clientId)) {
1924
+ unreadTerminals.add(d.clientId);
1925
+ updateClientList();
1926
+ }
1908
1927
  }
1909
1928
  break;
1910
1929
  }