nothumanallowed 9.8.5 → 9.8.7
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 +1 -1
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +127 -45
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "9.8.
|
|
3
|
+
"version": "9.8.7",
|
|
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 = '9.8.
|
|
8
|
+
export const VERSION = '9.8.7';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -257,11 +257,11 @@ function showBrowserViewer(title,status){
|
|
|
257
257
|
var t=document.getElementById('bvTitle');if(t)t.textContent=title||'Browser';
|
|
258
258
|
var s=document.getElementById('bvStatus');if(s)s.textContent=status||'Loading...';
|
|
259
259
|
}
|
|
260
|
-
function updateBrowserFrame(base64,format){
|
|
260
|
+
function updateBrowserFrame(base64,format,url){
|
|
261
261
|
var f=document.getElementById('bvFrame');if(!f)return;
|
|
262
262
|
f.innerHTML='<img src="data:image/'+(format||'jpeg')+';base64,'+base64+'" alt="Browser view">';
|
|
263
|
-
//
|
|
264
|
-
|
|
263
|
+
// Save to per-conversation browser history for canvas Browser tab
|
|
264
|
+
addBrowserPage(base64,url);
|
|
265
265
|
}
|
|
266
266
|
function updateBrowserStatus(status){
|
|
267
267
|
var s=document.getElementById('bvStatus');if(s)s.textContent=status;
|
|
@@ -271,7 +271,7 @@ function closeBrowserViewer(){
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
function loadConvList(){return apiGet('/api/conversations').then(function(r){convList=(r&&r.conversations)||[];renderConvSidebar();})}
|
|
274
|
-
function loadConv(id){return apiGet('/api/conversations/'+id).then(function(r){if(r&&r.conversation){activeConvId=r.conversation.id;chatHistory=r.conversation.messages||[];renderMessages();renderConvSidebar();}})}
|
|
274
|
+
function loadConv(id){return apiGet('/api/conversations/'+id).then(function(r){if(r&&r.conversation){activeConvId=r.conversation.id;chatHistory=r.conversation.messages||[];renderMessages();renderConvSidebar();onConversationSwitch();}})}
|
|
275
275
|
function createNewConv(){return apiPost('/api/conversations',{}).then(function(r){if(r&&r.conversation){activeConvId=r.conversation.id;chatHistory=[];renderMessages();loadConvList();}})}
|
|
276
276
|
function deleteConv(id){return fetch(API+'/api/conversations/'+id,{method:'DELETE'}).then(function(){loadConvList();if(id===activeConvId)createNewConv();})}
|
|
277
277
|
function clearChatHistory(){createNewConv()}
|
|
@@ -409,7 +409,7 @@ function renderChat(el){
|
|
|
409
409
|
'</div>'+
|
|
410
410
|
'<div class="chat"><div class="chat__messages" id="chatMessages"></div>'+
|
|
411
411
|
'<div id="chatAttachInfo" style="display:none;padding:4px 12px;font-size:11px;color:var(--cyan);background:var(--bg2);border-top:1px solid var(--border)"><span id="chatAttachName"></span> <button onclick="clearChatAttach()" style="background:none;border:none;color:#f44;cursor:pointer;font-size:14px;font-weight:700">×</button></div>'+
|
|
412
|
-
'<div class="chat__bar"><button class="chat__mic" id="chatMic" onclick="toggleVoiceInput()" title="Voice input">🎤</button><button onclick="document.getElementById(\\x27chatFileInput\\x27).click()" style="background:none;border:none;cursor:pointer;font-size:16px;padding:4px" title="Attach file">📎</button><button onclick="document.getElementById(\\x27chatImageInput\\x27).click()" style="background:none;border:none;cursor:pointer;font-size:16px;padding:4px" title="Attach image">📷</button><input type="file" id="chatFileInput" style="display:none" onchange="handleChatFile(this)"><input type="file" id="chatImageInput" accept="image/*" style="display:none" onchange="handleChatImage(this)"><textarea class="chat__input" id="chatInput" placeholder="Ask anything... (or attach file/image first)" rows="1"></textarea><button class="chat__send" id="chatSend">Send</button><button class="chat__stop" id="chatStop" onclick="stopChat()">Stop</button><button onclick="reopenCanvas()" style="background:none;border:
|
|
412
|
+
'<div class="chat__bar"><button class="chat__mic" id="chatMic" onclick="toggleVoiceInput()" title="Voice input">🎤</button><button onclick="document.getElementById(\\x27chatFileInput\\x27).click()" style="background:none;border:none;cursor:pointer;font-size:16px;padding:4px" title="Attach file">📎</button><button onclick="document.getElementById(\\x27chatImageInput\\x27).click()" style="background:none;border:none;cursor:pointer;font-size:16px;padding:4px" title="Attach image">📷</button><input type="file" id="chatFileInput" style="display:none" onchange="handleChatFile(this)"><input type="file" id="chatImageInput" accept="image/*" style="display:none" onchange="handleChatImage(this)"><textarea class="chat__input" id="chatInput" placeholder="Ask anything... (or attach file/image first)" rows="1"></textarea><button class="chat__send" id="chatSend">Send</button><button class="chat__stop" id="chatStop" onclick="stopChat()">Stop</button><button onclick="reopenCanvas()" style="background:none;border:1px solid var(--border2);border-radius:6px;cursor:pointer;font-size:11px;padding:4px 8px;color:var(--dim);font-family:var(--mono);display:flex;align-items:center;gap:4px" title="Open Canvas / Browser panel"><span style="font-size:14px">▣</span>Canvas</button></div>'+
|
|
413
413
|
'</div>'+
|
|
414
414
|
'</div>'+
|
|
415
415
|
'</div>';
|
|
@@ -524,68 +524,152 @@ function clearChatAttach(){
|
|
|
524
524
|
document.getElementById('chatImageInput').value='';
|
|
525
525
|
}
|
|
526
526
|
|
|
527
|
-
// ---- CANVAS (
|
|
528
|
-
var
|
|
529
|
-
var canvasIdx=-1;
|
|
530
|
-
var
|
|
531
|
-
var
|
|
527
|
+
// ---- CANVAS + BROWSER (per-conversation history) ----
|
|
528
|
+
var allCanvasData={}; // {convId: {canvases:[{html,title,ts}], browsers:[{base64,url,ts}]}}
|
|
529
|
+
var canvasIdx=-1;
|
|
530
|
+
var browserIdx=-1;
|
|
531
|
+
var canvasMode='canvas';
|
|
532
|
+
|
|
533
|
+
function getConvCanvasData(){
|
|
534
|
+
var id=activeConvId||'_default';
|
|
535
|
+
if(!allCanvasData[id])allCanvasData[id]={canvases:[],browsers:[]};
|
|
536
|
+
return allCanvasData[id];
|
|
537
|
+
}
|
|
532
538
|
|
|
533
539
|
function showCanvas(html,title){
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
canvasIdx=
|
|
540
|
+
var d=getConvCanvasData();
|
|
541
|
+
d.canvases.push({html:html,title:title||'Canvas',ts:new Date().toLocaleTimeString()});
|
|
542
|
+
canvasIdx=d.canvases.length-1;
|
|
537
543
|
canvasMode='canvas';
|
|
538
544
|
renderCanvasPanel();
|
|
539
|
-
|
|
540
|
-
|
|
545
|
+
saveCanvasData();
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function addBrowserPage(base64,url){
|
|
549
|
+
var d=getConvCanvasData();
|
|
550
|
+
var cleanUrl=(url||'Browser').replace(/^https?:\\/\\//, '').slice(0,60);
|
|
551
|
+
// Only add if URL is different from the last entry (avoid frame duplicates)
|
|
552
|
+
if(d.browsers.length>0&&d.browsers[d.browsers.length-1].url===cleanUrl){
|
|
553
|
+
// Update the thumbnail with the latest frame
|
|
554
|
+
d.browsers[d.browsers.length-1].base64=base64;
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
d.browsers.push({base64:base64,url:cleanUrl,ts:new Date().toLocaleTimeString()});
|
|
558
|
+
browserIdx=d.browsers.length-1;
|
|
559
|
+
// Auto-update canvas panel if browser tab is open
|
|
560
|
+
var p=document.getElementById('canvasPanel');
|
|
561
|
+
if(p&&p.classList.contains('open')&&canvasMode==='browser'){renderCanvasPanel();}
|
|
541
562
|
}
|
|
542
563
|
|
|
564
|
+
function saveCanvasData(){
|
|
565
|
+
// Save only canvas HTML (not browser base64 — too large) per conversation
|
|
566
|
+
try{
|
|
567
|
+
var save={};
|
|
568
|
+
for(var id in allCanvasData){
|
|
569
|
+
if(allCanvasData[id].canvases.length>0){
|
|
570
|
+
save[id]={canvases:allCanvasData[id].canvases.slice(-20)};
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
localStorage.setItem('nha_canvas_data',JSON.stringify(save));
|
|
574
|
+
}catch(e){}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function loadCanvasData(){
|
|
578
|
+
try{
|
|
579
|
+
var saved=localStorage.getItem('nha_canvas_data');
|
|
580
|
+
if(saved){
|
|
581
|
+
var parsed=JSON.parse(saved);
|
|
582
|
+
for(var id in parsed){
|
|
583
|
+
if(!allCanvasData[id])allCanvasData[id]={canvases:[],browsers:[]};
|
|
584
|
+
allCanvasData[id].canvases=parsed[id].canvases||[];
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}catch(e){}
|
|
588
|
+
}
|
|
589
|
+
loadCanvasData();
|
|
590
|
+
|
|
543
591
|
function renderCanvasPanel(){
|
|
544
592
|
var p=document.getElementById('canvasPanel');
|
|
545
593
|
if(!p)return;
|
|
546
594
|
p.classList.add('open');
|
|
547
|
-
var
|
|
548
|
-
|
|
595
|
+
var d=getConvCanvasData();
|
|
596
|
+
var list=canvasMode==='browser'?d.browsers:d.canvases;
|
|
597
|
+
var idx=canvasMode==='browser'?browserIdx:canvasIdx;
|
|
598
|
+
var item=list[idx];
|
|
599
|
+
// Header title
|
|
549
600
|
var t=document.getElementById('canvasTitle');
|
|
550
601
|
if(t){
|
|
551
|
-
if(canvasMode==='browser'){t.textContent='
|
|
552
|
-
else if(item){t.textContent=
|
|
553
|
-
else{t.textContent='Canvas';}
|
|
602
|
+
if(canvasMode==='browser'){t.textContent=d.browsers.length>0?d.browsers.length+' pages visited':'No pages visited';}
|
|
603
|
+
else if(!item){t.textContent='Empty canvas';}
|
|
604
|
+
else{t.textContent=(item.title||'Canvas')+(d.canvases.length>1?' ('+(canvasIdx+1)+'/'+d.canvases.length+')':'');}
|
|
554
605
|
}
|
|
555
|
-
//
|
|
606
|
+
// Nav arrows — only for canvas mode (browser uses gallery grid)
|
|
556
607
|
var navEl=document.getElementById('canvasNav');
|
|
557
|
-
if(navEl){navEl.style.display=
|
|
558
|
-
//
|
|
608
|
+
if(navEl){navEl.style.display=d.canvases.length>1&&canvasMode==='canvas'?'flex':'none';}
|
|
609
|
+
// Tab highlight
|
|
559
610
|
var tabC=document.getElementById('canvasTabC');
|
|
560
611
|
var tabB=document.getElementById('canvasTabB');
|
|
561
612
|
if(tabC)tabC.style.borderBottom=canvasMode==='canvas'?'2px solid var(--green)':'none';
|
|
562
613
|
if(tabB)tabB.style.borderBottom=canvasMode==='browser'?'2px solid var(--green)':'none';
|
|
563
|
-
// Render content
|
|
564
|
-
var f=document.getElementById('canvasFrame');
|
|
565
|
-
|
|
566
|
-
if(canvasMode==='browser'
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
614
|
+
// Render iframe content
|
|
615
|
+
var f=document.getElementById('canvasFrame');if(!f)return;
|
|
616
|
+
var doc=f.contentDocument||f.contentWindow.document;
|
|
617
|
+
if(canvasMode==='browser'){
|
|
618
|
+
// Browser tab: gallery of visited page thumbnails
|
|
619
|
+
var d=getConvCanvasData();
|
|
620
|
+
if(d.browsers.length===0){
|
|
621
|
+
doc.open();doc.write('<html><body style="margin:0;background:#111;display:flex;align-items:center;justify-content:center;height:100vh;font-family:monospace;color:#555"><div style="text-align:center"><div style="font-size:48px;margin-bottom:12px">🌐</div><div>No pages visited</div><div style="font-size:11px;margin-top:8px;color:#333">in this conversation</div></div></body></html>');doc.close();
|
|
622
|
+
} else {
|
|
623
|
+
var gallery='<html><head><style>*{margin:0;padding:0;box-sizing:border-box}body{background:#111;padding:12px;font-family:monospace}h3{color:#00ff41;font-size:12px;margin-bottom:12px}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px}.card{background:#1a1a1a;border:1px solid #333;border-radius:8px;overflow:hidden;cursor:pointer;transition:border-color .2s}.card:hover{border-color:#00ff41}.card img{width:100%;height:120px;object-fit:cover;display:block}.card .info{padding:6px 8px}.card .url{color:#8ab4f8;font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.card .time{color:#555;font-size:9px;margin-top:2px}.selected{border-color:#00ff41;box-shadow:0 0 10px rgba(0,255,65,0.2)}</style></head><body><h3>Pages visited ('+d.browsers.length+')</h3><div class="grid">';
|
|
624
|
+
for(var bi=0;bi<d.browsers.length;bi++){
|
|
625
|
+
var b=d.browsers[bi];
|
|
626
|
+
var sel=bi===browserIdx?' selected':'';
|
|
627
|
+
gallery+='<div class="card'+sel+'" onclick="parent.selectBrowserPage('+bi+')"><img src="data:image/jpeg;base64,'+b.base64+'" alt="'+b.url+'"/><div class="info"><div class="url">'+b.url+'</div><div class="time">'+b.ts+'</div></div></div>';
|
|
628
|
+
}
|
|
629
|
+
gallery+='</div></body></html>';
|
|
630
|
+
doc.open();doc.write(gallery);doc.close();
|
|
631
|
+
}
|
|
632
|
+
} else if(!item){
|
|
633
|
+
doc.open();doc.write('<html><body style="margin:0;background:#111;display:flex;align-items:center;justify-content:center;height:100vh;font-family:monospace;color:#555"><div style="text-align:center"><div style="font-size:48px;margin-bottom:12px">▣</div><div>No canvas content</div><div style="font-size:11px;margin-top:8px;color:#333">in this conversation</div></div></body></html>');doc.close();
|
|
634
|
+
} else {
|
|
571
635
|
doc.open();doc.write(item.html);doc.close();
|
|
572
636
|
}
|
|
573
637
|
}
|
|
574
638
|
|
|
575
|
-
function canvasPrev(){
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
639
|
+
function canvasPrev(){
|
|
640
|
+
var d=getConvCanvasData();
|
|
641
|
+
if(canvasMode==='browser'){if(browserIdx>0){browserIdx--;renderCanvasPanel();}}
|
|
642
|
+
else{if(canvasIdx>0){canvasIdx--;renderCanvasPanel();}}
|
|
643
|
+
}
|
|
644
|
+
function canvasNext(){
|
|
645
|
+
var d=getConvCanvasData();
|
|
646
|
+
if(canvasMode==='browser'){if(browserIdx<d.browsers.length-1){browserIdx++;renderCanvasPanel();}}
|
|
647
|
+
else{if(canvasIdx<d.canvases.length-1){canvasIdx++;renderCanvasPanel();}}
|
|
648
|
+
}
|
|
649
|
+
function selectBrowserPage(i){browserIdx=i;canvasMode='browser';renderCanvasPanel();}
|
|
650
|
+
function canvasShowBrowser(){var d=getConvCanvasData();browserIdx=d.browsers.length-1;canvasMode='browser';renderCanvasPanel();}
|
|
651
|
+
function canvasShowCanvas(){var d=getConvCanvasData();canvasIdx=d.canvases.length-1;canvasMode='canvas';renderCanvasPanel();}
|
|
579
652
|
|
|
580
|
-
function
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
653
|
+
function onConversationSwitch(){
|
|
654
|
+
// Called when user switches conversation — update canvas panel
|
|
655
|
+
var p=document.getElementById('canvasPanel');
|
|
656
|
+
if(p&&p.classList.contains('open')){
|
|
657
|
+
var d=getConvCanvasData();
|
|
658
|
+
canvasIdx=d.canvases.length-1;
|
|
659
|
+
browserIdx=d.browsers.length-1;
|
|
660
|
+
renderCanvasPanel();
|
|
584
661
|
}
|
|
585
|
-
if(canvasHistory.length>0){canvasIdx=canvasHistory.length-1;canvasMode='canvas';renderCanvasPanel();}
|
|
586
|
-
else if(lastBrowserFrame){canvasMode='browser';renderCanvasPanel();}
|
|
587
662
|
}
|
|
588
663
|
|
|
664
|
+
function reopenCanvas(){
|
|
665
|
+
var d=getConvCanvasData();
|
|
666
|
+
canvasIdx=d.canvases.length-1;
|
|
667
|
+
browserIdx=d.browsers.length-1;
|
|
668
|
+
if(d.canvases.length>0){canvasMode='canvas';}
|
|
669
|
+
else if(d.browsers.length>0){canvasMode='browser';}
|
|
670
|
+
else{canvasMode='canvas';} // show empty state
|
|
671
|
+
renderCanvasPanel();
|
|
672
|
+
}
|
|
589
673
|
function closeCanvas(){var p=document.getElementById('canvasPanel');if(p)p.classList.remove('open');}
|
|
590
674
|
function toggleCanvasSize(){
|
|
591
675
|
var p=document.getElementById('canvasPanel');if(!p)return;
|
|
@@ -694,15 +778,13 @@ function sendChat(){
|
|
|
694
778
|
renderMessages();
|
|
695
779
|
}
|
|
696
780
|
if(currentEvent==='screenshot'&&data.base64){
|
|
697
|
-
// Only update the browser viewer — the actual image in chat is handled by the 'done' event via screenshotFiles
|
|
698
781
|
showBrowserViewer('Screenshot','Captured');
|
|
699
|
-
updateBrowserFrame(data.base64,data.format||'jpeg');
|
|
782
|
+
updateBrowserFrame(data.base64,data.format||'jpeg','Screenshot');
|
|
700
783
|
updateBrowserStatus('Screenshot captured');
|
|
701
784
|
}
|
|
702
785
|
if(currentEvent==='browser_frame'&&data.base64){
|
|
703
|
-
// Live frame update — also ensure viewer is open
|
|
704
786
|
showBrowserViewer(data.url||'Browser','Live');
|
|
705
|
-
updateBrowserFrame(data.base64,data.format||'jpeg');
|
|
787
|
+
updateBrowserFrame(data.base64,data.format||'jpeg',data.url||'Browser');
|
|
706
788
|
if(data.url)updateBrowserStatus(data.url);
|
|
707
789
|
}
|
|
708
790
|
if(currentEvent==='canvas'&&data.markers){
|