nothumanallowed 10.3.2 → 10.4.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nothumanallowed",
3
- "version": "10.3.2",
3
+ "version": "10.4.0",
4
4
  "description": "NotHumanAllowed — 38 AI agents, 53 tools. Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, GitHub, Notion, Slack, voice chat, 28 languages. Zero-dependency CLI.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/constants.mjs CHANGED
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = path.dirname(__filename);
7
7
 
8
- export const VERSION = '10.3.2';
8
+ export const VERSION = '10.4.0';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -1596,6 +1596,78 @@ var collabChannels=[];
1596
1596
  var collabMessages=[];
1597
1597
  var collabActiveChannel=null;
1598
1598
  var collabPolling=null;
1599
+ var collabLastMessageCount=0;
1600
+ var collabUnreadCount=0;
1601
+ var collabGlobalPolling=null;
1602
+
1603
+ // Global polling — check for new messages across ALL channels every 3s (even when not on Collab tab)
1604
+ function startCollabGlobalPolling(){
1605
+ if(collabGlobalPolling)return;
1606
+ // Load channels first
1607
+ apiGet('/api/collab/channels').then(function(r){
1608
+ if(r&&r.channels)collabChannels=r.channels;
1609
+ }).catch(function(){});
1610
+ collabGlobalPolling=setInterval(function(){
1611
+ if(collabChannels.length===0)return;
1612
+ // Check each channel for new messages
1613
+ for(var i=0;i<collabChannels.length;i++){
1614
+ (function(ch){
1615
+ apiGet('/api/collab/messages?channelId='+ch.id).then(function(r){
1616
+ if(!r||!r.messages)return;
1617
+ var prevCount=ch._lastCount||0;
1618
+ var newCount=r.messages.length;
1619
+ if(newCount>prevCount&&prevCount>0){
1620
+ var diff=newCount-prevCount;
1621
+ collabUnreadCount+=diff;
1622
+ updateCollabBadge();
1623
+ // Show toast notification
1624
+ var lastMsg=r.messages[r.messages.length-1];
1625
+ if(lastMsg&&currentView!=='collab'){
1626
+ showToast('collab','AgentMessenger','New message in '+ch.name+': '+(lastMsg.content||'[encrypted]').slice(0,80),5000);
1627
+ }
1628
+ // Update messages if viewing this channel
1629
+ if(collabActiveChannel===ch.id&&currentView==='collab'){
1630
+ collabMessages=r.messages;
1631
+ renderCollabMessages();
1632
+ }
1633
+ }
1634
+ ch._lastCount=newCount;
1635
+ }).catch(function(){});
1636
+ })(collabChannels[i]);
1637
+ }
1638
+ },3000);
1639
+ }
1640
+
1641
+ function updateCollabBadge(){
1642
+ var badge=document.getElementById('collabBadge');
1643
+ if(badge){
1644
+ if(collabUnreadCount>0){
1645
+ badge.textContent=collabUnreadCount>99?'99+':collabUnreadCount;
1646
+ badge.style.display='inline-block';
1647
+ } else {
1648
+ badge.style.display='none';
1649
+ }
1650
+ }
1651
+ }
1652
+
1653
+ function renderCollabMessages(){
1654
+ var el=document.getElementById('collabMessages');if(!el)return;
1655
+ if(collabMessages.length===0){el.innerHTML='<div style="text-align:center;color:var(--dim);padding:20px;font-size:11px">No messages yet</div>';return;}
1656
+ var h='';
1657
+ for(var i=0;i<collabMessages.length;i++){
1658
+ var m=collabMessages[i];
1659
+ var time=new Date(m.timestamp).toLocaleTimeString();
1660
+ var sender=m.senderName||m.senderFingerprint?.slice(0,8)||'Unknown';
1661
+ var content=m.content||m.plaintext||'[encrypted]';
1662
+ if(m.type==='system'){h+='<div style="text-align:center;color:var(--dim);font-size:10px;margin:4px 0">'+esc(sender)+' joined</div>';continue;}
1663
+ h+='<div style="margin-bottom:8px"><span style="font-size:10px;color:var(--dim)">'+time+'</span> <span style="font-size:11px;color:var(--amber);font-weight:600">'+esc(sender)+'</span><div style="font-size:12px;color:var(--fg);margin-top:2px;white-space:pre-wrap">'+esc(content)+'</div></div>';
1664
+ }
1665
+ el.innerHTML=h;
1666
+ el.scrollTop=el.scrollHeight;
1667
+ }
1668
+
1669
+ // Start global polling on page load
1670
+ setTimeout(startCollabGlobalPolling,2000);
1599
1671
 
1600
1672
  function renderCollab(el){
1601
1673
  var h='<div style="max-width:800px;margin:0 auto;padding:20px">';
@@ -1643,7 +1715,7 @@ function renderCollabChannelList(){
1643
1715
  var active=collabActiveChannel===ch.id;
1644
1716
  h+='<div onclick="collabSelect(\\x27'+ch.id+'\\x27)" style="padding:8px 12px;cursor:pointer;border-left:3px solid '+(active?'var(--amber)':'transparent')+';background:'+(active?'var(--bg2)':'transparent')+';margin-bottom:2px;border-radius:0 6px 6px 0">';
1645
1717
  h+='<span style="font-size:12px;color:var(--fg)">'+esc(ch.name)+'</span>';
1646
- h+='<span style="font-size:9px;color:var(--dim);margin-left:8px">'+ch.id.slice(0,8)+'...</span>';
1718
+ h+='<span onclick="event.stopPropagation();navigator.clipboard.writeText(\\x27'+ch.id+'\\x27);this.textContent=\\x27copied!\\x27;setTimeout(function(){this.textContent=\\x27'+ch.id.slice(0,8)+'...\\x27}.bind(this),1500)" style="font-size:9px;color:var(--dim);margin-left:8px;cursor:pointer" title="Click to copy invite code: '+ch.id+'">'+ch.id.slice(0,8)+'...</span>';
1647
1719
  h+='<button onclick="event.stopPropagation();collabDeleteChannel(\\x27'+ch.id+'\\x27)" style="float:right;background:none;border:none;color:var(--red);cursor:pointer;font-size:10px;font-family:var(--mono);opacity:0.5" title="Delete channel">del</button>';
1648
1720
  h+='</div>';
1649
1721
  }
@@ -1691,29 +1763,27 @@ function collabDeleteChannel(id){
1691
1763
  function collabSelect(id){
1692
1764
  collabActiveChannel=id;
1693
1765
  collabLoadMessages();
1694
- // Auto-refresh every 5s while channel is selected
1766
+ // Auto-refresh every 2s while channel is selected
1695
1767
  if(collabPolling)clearInterval(collabPolling);
1696
- collabPolling=setInterval(function(){if(currentView==='collab'&&collabActiveChannel===id)collabLoadMessages();},5000);
1768
+ collabPolling=setInterval(function(){
1769
+ if(currentView==='collab'&&collabActiveChannel===id){
1770
+ collabLoadMessages();
1771
+ }
1772
+ },2000);
1697
1773
  }
1698
1774
 
1699
1775
  function collabLoadMessages(){
1700
1776
  if(!collabActiveChannel)return;
1777
+ // Reset unread when viewing
1778
+ collabUnreadCount=0;
1779
+ updateCollabBadge();
1701
1780
  apiGet('/api/collab/messages?channelId='+collabActiveChannel).then(function(r){
1702
1781
  if(!r||!r.messages)return;
1703
1782
  collabMessages=r.messages;
1704
- var el=document.getElementById('collabMessages');if(!el)return;
1705
- if(collabMessages.length===0){el.innerHTML='<div style="text-align:center;color:var(--dim);padding:20px;font-size:11px">No messages yet</div>';return;}
1706
- var h='';
1707
- for(var i=0;i<collabMessages.length;i++){
1708
- var m=collabMessages[i];
1709
- var time=new Date(m.timestamp).toLocaleTimeString();
1710
- var sender=m.senderName||m.senderFingerprint?.slice(0,8)||'Unknown';
1711
- var content=m.content||m.plaintext||'[encrypted]';
1712
- if(m.type==='system'){h+='<div style="text-align:center;color:var(--dim);font-size:10px;margin:4px 0">'+esc(sender)+' joined</div>';continue;}
1713
- h+='<div style="margin-bottom:8px"><span style="font-size:10px;color:var(--dim)">'+time+'</span> <span style="font-size:11px;color:var(--amber);font-weight:600">'+esc(sender)+'</span><div style="font-size:12px;color:var(--fg);margin-top:2px;white-space:pre-wrap">'+esc(content)+'</div></div>';
1714
- }
1715
- el.innerHTML=h;
1716
- el.scrollTop=el.scrollHeight;
1783
+ // Update last count for this channel
1784
+ var ch=collabChannels.find(function(c){return c.id===collabActiveChannel});
1785
+ if(ch)ch._lastCount=r.messages.length;
1786
+ renderCollabMessages();
1717
1787
  });
1718
1788
  }
1719
1789
 
@@ -1721,9 +1791,13 @@ function collabSend(){
1721
1791
  var inp=document.getElementById('collabInput');if(!inp)return;
1722
1792
  var msg=inp.value.trim();if(!msg||!collabActiveChannel)return;
1723
1793
  inp.value='';
1794
+ // Optimistic: show message immediately
1795
+ collabMessages.push({senderName:'You',timestamp:new Date().toISOString(),content:msg,type:'text'});
1796
+ renderCollabMessages();
1724
1797
  apiPost('/api/collab/send',{channelId:collabActiveChannel,message:msg}).then(function(r){
1725
1798
  if(r.error){alert(r.error);return;}
1726
- collabLoadMessages();
1799
+ // Reload to get server timestamp
1800
+ setTimeout(collabLoadMessages,500);
1727
1801
  });
1728
1802
  }
1729
1803
 
@@ -2278,7 +2352,7 @@ init();
2278
2352
  <div class="sidebar__section">
2279
2353
  <div class="sidebar__label">AI</div>
2280
2354
  <div class="nav-item" data-view="agents" onclick="switchView('agents')"><span class="nav-item__icon">&#129302;</span> Agents</div>
2281
- <div class="nav-item" data-view="collab" onclick="switchView('collab')"><span class="nav-item__icon">&#128274;</span> AgentMessenger</div>
2355
+ <div class="nav-item" data-view="collab" onclick="switchView('collab')"><span class="nav-item__icon">&#128274;</span> AgentMessenger <span id="collabBadge" style="display:none;background:var(--red);color:#fff;font-size:9px;padding:1px 5px;border-radius:8px;margin-left:4px;font-family:var(--mono)">0</span></div>
2282
2356
  </div>
2283
2357
  <div class="sidebar__section">
2284
2358
  <div class="sidebar__label">Config</div>