nothumanallowed 9.8.9 → 9.9.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 +1 -1
- package/src/commands/ui.mjs +13 -4
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +28 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.9.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/commands/ui.mjs
CHANGED
|
@@ -1414,7 +1414,7 @@ export async function cmdUI(args) {
|
|
|
1414
1414
|
toolResults.push({ action, result: resultStr });
|
|
1415
1415
|
sendSSE('tool', { action, status: 'done', result: typeof resultStr === 'string' ? resultStr.slice(0, 500) : '' });
|
|
1416
1416
|
|
|
1417
|
-
// Send live browser frame after browser actions
|
|
1417
|
+
// Send live browser frame after browser actions — save as thumbnail file for persistence
|
|
1418
1418
|
if (action.startsWith('browser_') && action !== 'browser_close') {
|
|
1419
1419
|
try {
|
|
1420
1420
|
const be = await import('../services/browser-engine.mjs');
|
|
@@ -1422,7 +1422,15 @@ export async function cmdUI(args) {
|
|
|
1422
1422
|
const frame = await be.browserScreenshot({ fullPage: false, format: 'jpeg', quality: 30 });
|
|
1423
1423
|
if (!frame.error) {
|
|
1424
1424
|
const info = await be.browserInfo();
|
|
1425
|
-
|
|
1425
|
+
const pageUrl = (info.url || '').slice(0, 80);
|
|
1426
|
+
// Save thumbnail to disk for persistence
|
|
1427
|
+
const thumbDir = path.join(NHA_DIR, 'screenshots');
|
|
1428
|
+
fs.mkdirSync(thumbDir, { recursive: true });
|
|
1429
|
+
const thumbFile = `thumb-${Date.now()}.jpg`;
|
|
1430
|
+
fs.writeFileSync(path.join(thumbDir, thumbFile), Buffer.from(frame.base64, 'base64'));
|
|
1431
|
+
if (!res._browserThumbs) res._browserThumbs = [];
|
|
1432
|
+
res._browserThumbs.push({ file: thumbFile, url: pageUrl });
|
|
1433
|
+
sendSSE('browser_frame', { file: thumbFile, format: 'jpeg', url: pageUrl });
|
|
1426
1434
|
}
|
|
1427
1435
|
}
|
|
1428
1436
|
} catch { /* frame capture failed, non-critical */ }
|
|
@@ -1442,7 +1450,7 @@ export async function cmdUI(args) {
|
|
|
1442
1450
|
const ssBase64 = fs.readFileSync(ssPath).toString('base64');
|
|
1443
1451
|
console.log(` [screenshot] sending SSE, base64 size: ${ssBase64.length}`);
|
|
1444
1452
|
sendSSE('screenshot', { base64: ssBase64, format: 'jpeg', filename: ssFilename });
|
|
1445
|
-
sendSSE('browser_frame', {
|
|
1453
|
+
sendSSE('browser_frame', { file: ssFilename, format: 'jpeg', url: 'Search results' });
|
|
1446
1454
|
if (!res._screenshotFiles) res._screenshotFiles = [];
|
|
1447
1455
|
res._screenshotFiles.push(ssFilename);
|
|
1448
1456
|
}
|
|
@@ -1512,7 +1520,8 @@ export async function cmdUI(args) {
|
|
|
1512
1520
|
try { extractMemory('chat', msg, finalResponse); } catch {}
|
|
1513
1521
|
|
|
1514
1522
|
const ssFiles = res._screenshotFiles || [];
|
|
1515
|
-
|
|
1523
|
+
const browserThumbs = res._browserThumbs || [];
|
|
1524
|
+
sendSSE('done', { content: finalResponse, screenshotFiles: ssFiles, browserThumbs });
|
|
1516
1525
|
} catch (e) {
|
|
1517
1526
|
sendSSE('error', { message: e.message });
|
|
1518
1527
|
}
|
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
|
+
export const VERSION = '9.9.0';
|
|
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
|
@@ -260,11 +260,13 @@ function showBrowserViewer(title,status){
|
|
|
260
260
|
var p=document.getElementById('canvasPanel');
|
|
261
261
|
if(p&&!p.classList.contains('open')){canvasMode='browser';renderCanvasPanel();}
|
|
262
262
|
}
|
|
263
|
-
function updateBrowserFrame(
|
|
263
|
+
function updateBrowserFrame(data){
|
|
264
|
+
// data = {base64?, file?, format, url}
|
|
265
|
+
var imgSrc=data.file?API+'/api/screenshots/'+data.file:'data:image/'+(data.format||'jpeg')+';base64,'+data.base64;
|
|
264
266
|
// Update old monitor viewer
|
|
265
|
-
var f=document.getElementById('bvFrame');if(f)f.innerHTML='<img src="
|
|
267
|
+
var f=document.getElementById('bvFrame');if(f)f.innerHTML='<img src="'+imgSrc+'" alt="Browser view">';
|
|
266
268
|
// Save to per-conversation browser history for canvas Browser tab
|
|
267
|
-
addBrowserPage(base64,url);
|
|
269
|
+
addBrowserPage(data.file||null,data.base64||null,data.url);
|
|
268
270
|
// Update canvas browser tab live if open
|
|
269
271
|
var p=document.getElementById('canvasPanel');
|
|
270
272
|
if(p&&p.classList.contains('open')&&canvasMode==='browser'){renderCanvasPanel();}
|
|
@@ -551,29 +553,33 @@ function showCanvas(html,title){
|
|
|
551
553
|
saveCanvasData();
|
|
552
554
|
}
|
|
553
555
|
|
|
554
|
-
function addBrowserPage(base64,url){
|
|
556
|
+
function addBrowserPage(file,base64,url){
|
|
555
557
|
var d=getConvCanvasData();
|
|
556
558
|
var cleanUrl=(url||'Browser').replace(/^https?:\\/\\//, '').slice(0,60);
|
|
557
559
|
// Only add if URL is different from the last entry (avoid frame duplicates)
|
|
558
560
|
if(d.browsers.length>0&&d.browsers[d.browsers.length-1].url===cleanUrl){
|
|
559
|
-
// Update the thumbnail
|
|
560
|
-
d.browsers[d.browsers.length-1].
|
|
561
|
+
// Update the thumbnail file ref
|
|
562
|
+
if(file)d.browsers[d.browsers.length-1].file=file;
|
|
563
|
+
if(base64)d.browsers[d.browsers.length-1].base64=base64;
|
|
561
564
|
return;
|
|
562
565
|
}
|
|
563
|
-
d.browsers.push({base64:base64,url:cleanUrl,ts:new Date().toLocaleTimeString()});
|
|
566
|
+
d.browsers.push({file:file,base64:base64,url:cleanUrl,ts:new Date().toLocaleTimeString()});
|
|
564
567
|
browserIdx=d.browsers.length-1;
|
|
565
|
-
//
|
|
566
|
-
|
|
567
|
-
if(p&&p.classList.contains('open')&&canvasMode==='browser'){renderCanvasPanel();}
|
|
568
|
+
// Persist file refs to localStorage (not base64)
|
|
569
|
+
saveCanvasData();
|
|
568
570
|
}
|
|
569
571
|
|
|
570
572
|
function saveCanvasData(){
|
|
571
|
-
// Save only canvas HTML (not browser base64 — too large) per conversation
|
|
572
573
|
try{
|
|
573
574
|
var save={};
|
|
574
575
|
for(var id in allCanvasData){
|
|
575
|
-
|
|
576
|
-
|
|
576
|
+
var d=allCanvasData[id];
|
|
577
|
+
if(d.canvases.length>0||d.browsers.length>0){
|
|
578
|
+
save[id]={
|
|
579
|
+
canvases:d.canvases.slice(-20),
|
|
580
|
+
// Save browser entries with file refs only (no base64)
|
|
581
|
+
browsers:d.browsers.slice(-30).map(function(b){return {file:b.file,url:b.url,ts:b.ts};})
|
|
582
|
+
};
|
|
577
583
|
}
|
|
578
584
|
}
|
|
579
585
|
localStorage.setItem('nha_canvas_data',JSON.stringify(save));
|
|
@@ -588,6 +594,7 @@ function loadCanvasData(){
|
|
|
588
594
|
for(var id in parsed){
|
|
589
595
|
if(!allCanvasData[id])allCanvasData[id]={canvases:[],browsers:[]};
|
|
590
596
|
allCanvasData[id].canvases=parsed[id].canvases||[];
|
|
597
|
+
allCanvasData[id].browsers=parsed[id].browsers||[];
|
|
591
598
|
}
|
|
592
599
|
}
|
|
593
600
|
}catch(e){}
|
|
@@ -626,11 +633,12 @@ function renderCanvasPanel(){
|
|
|
626
633
|
if(d.browsers.length===0){
|
|
627
634
|
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();
|
|
628
635
|
} else {
|
|
629
|
-
var
|
|
636
|
+
var apiBase=window.API||'';
|
|
637
|
+
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;background:#222}.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}</style></head><body><h3>Pages visited ('+d.browsers.length+')</h3><div class="grid">';
|
|
630
638
|
for(var bi=0;bi<d.browsers.length;bi++){
|
|
631
639
|
var b=d.browsers[bi];
|
|
632
|
-
var
|
|
633
|
-
gallery+='<div class="card
|
|
640
|
+
var imgSrc=b.file?apiBase+'/api/screenshots/'+b.file:(b.base64?'data:image/jpeg;base64,'+b.base64:'');
|
|
641
|
+
gallery+='<div class="card" onclick="parent.selectBrowserPage('+bi+')">'+(imgSrc?'<img src="'+imgSrc+'" alt="'+b.url+'"/>':'<div style="height:120px;display:flex;align-items:center;justify-content:center;color:#555">No preview</div>')+'<div class="info"><div class="url">'+b.url+'</div><div class="time">'+(b.ts||'')+'</div></div></div>';
|
|
634
642
|
}
|
|
635
643
|
gallery+='</div></body></html>';
|
|
636
644
|
doc.open();doc.write(gallery);doc.close();
|
|
@@ -785,12 +793,12 @@ function sendChat(){
|
|
|
785
793
|
}
|
|
786
794
|
if(currentEvent==='screenshot'&&data.base64){
|
|
787
795
|
showBrowserViewer('Screenshot','Captured');
|
|
788
|
-
updateBrowserFrame(data.base64,data.format||'jpeg','Screenshot');
|
|
796
|
+
updateBrowserFrame({base64:data.base64,format:data.format||'jpeg',url:'Screenshot'});
|
|
789
797
|
updateBrowserStatus('Screenshot captured');
|
|
790
798
|
}
|
|
791
|
-
if(currentEvent==='browser_frame'&&data.base64){
|
|
799
|
+
if(currentEvent==='browser_frame'&&(data.base64||data.file)){
|
|
792
800
|
showBrowserViewer(data.url||'Browser','Live');
|
|
793
|
-
updateBrowserFrame(data
|
|
801
|
+
updateBrowserFrame(data);
|
|
794
802
|
if(data.url)updateBrowserStatus(data.url);
|
|
795
803
|
}
|
|
796
804
|
if(currentEvent==='canvas'&&data.markers){
|
|
@@ -800,7 +808,7 @@ function sendChat(){
|
|
|
800
808
|
if(data.markers.indexOf('[CANVAS_CLEAR]')!==-1)closeCanvas();
|
|
801
809
|
}
|
|
802
810
|
if(currentEvent==='tool_synthesis'){chatHistory[streamIdx].content='';renderMessages();}
|
|
803
|
-
if(currentEvent==='done'){endStreaming();if(data.content)chatHistory[streamIdx].content=data.content;var ssf=data.screenshotFiles||[];for(var fi=0;fi<ssf.length;fi++){chatHistory[streamIdx].content+='\\n\\n';}renderMessages();loadConvList();if(ssf.length>0)setTimeout(closeBrowserViewer,5000);}
|
|
811
|
+
if(currentEvent==='done'){endStreaming();if(data.content)chatHistory[streamIdx].content=data.content;var ssf=data.screenshotFiles||[];for(var fi=0;fi<ssf.length;fi++){chatHistory[streamIdx].content+='\\n\\n';}var bt=data.browserThumbs||[];if(bt.length>0){var cd=getConvCanvasData();for(var bti=0;bti<bt.length;bti++){var exists=cd.browsers.some(function(b){return b.file===bt[bti].file;});if(!exists)cd.browsers.push({file:bt[bti].file,url:bt[bti].url,ts:new Date().toLocaleTimeString()});}browserIdx=cd.browsers.length-1;saveCanvasData();}renderMessages();loadConvList();if(ssf.length>0)setTimeout(closeBrowserViewer,5000);}
|
|
804
812
|
if(currentEvent==='error'){endStreaming();chatHistory[streamIdx].content='Error: '+(data.message||'Unknown');renderMessages();}
|
|
805
813
|
}catch(e){}
|
|
806
814
|
}
|