nothumanallowed 12.4.0 → 12.5.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": "12.4.0",
3
+ "version": "12.5.0",
4
4
  "description": "NotHumanAllowed — 38 AI agents, 80 tools. Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2074,12 +2074,14 @@ export async function cmdUI(args) {
2074
2074
  // Extract memory
2075
2075
  try { extractMemory('chat', msg, finalResponse); } catch {}
2076
2076
 
2077
- // Append inline embeds (search cards, browser frames) to the response
2078
- if (inlineEmbeds) finalResponse += '\n' + inlineEmbeds;
2077
+ // Send inline embeds (search cards, browser frames) via SSE
2078
+ if (inlineEmbeds) {
2079
+ sendSSE('inline_embeds', { html: inlineEmbeds });
2080
+ }
2079
2081
 
2080
2082
  const ssFiles = res._screenshotFiles || [];
2081
2083
  const browserThumbs = res._browserThumbs || [];
2082
- sendSSE('done', { content: finalResponse, screenshotFiles: ssFiles, browserThumbs });
2084
+ sendSSE('done', { content: finalResponse, screenshotFiles: ssFiles, browserThumbs, inlineHtml: inlineEmbeds || '' });
2083
2085
  } catch (e) {
2084
2086
  sendSSE('error', { message: e.message });
2085
2087
  }
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 = '12.4.0';
8
+ export const VERSION = '12.5.0';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -495,7 +495,11 @@ function renderMessages(){
495
495
  // Fork navigation placeholder (filled after render by loadForkInfo)
496
496
  if(m.id){acts+='<span class="msg__fork" data-node-id="'+m.id+'"></span>';}
497
497
  acts+='</div>';
498
- h+='<div class="msg msg--'+esc(m.role)+'"><div class="msg__label">'+esc(m.role==='user'?'You':'NHA')+'</div><div class="msg__bubble">'+content+'</div>'+acts+'</div>';
498
+ var inlineBlock='';
499
+ if(isA&&m.inlineHtml){
500
+ inlineBlock=m.inlineHtml.replace(/\\[INLINE_CARD\\]([\\s\\S]*?)\\[\\/INLINE_CARD\\]/g,function(_,htm){return '<div class="inline-card">'+htm+'</div>';}).replace(/\\[INLINE_BROWSER\\]([^|]+)\\|([^\\]]+)\\[\\/INLINE_BROWSER\\]/g,function(_,file,url){return '<div class="inline-browser"><div class="inline-browser-bar"><span class="inline-browser-dot"></span><span class="inline-browser-dot"></span><span class="inline-browser-dot"></span><span class="inline-browser-url">'+esc(url)+'</span></div><img src="/api/screenshots/'+esc(file)+'" alt="'+esc(url)+'"></div>';});
501
+ }
502
+ h+='<div class="msg msg--'+esc(m.role)+'"><div class="msg__label">'+esc(m.role==='user'?'You':'NHA')+'</div><div class="msg__bubble">'+content+'</div>'+inlineBlock+acts+'</div>';
499
503
  });
500
504
  el.innerHTML=h;el.scrollTop=el.scrollHeight;
501
505
  // Load fork info for messages that have IDs
@@ -729,8 +733,7 @@ function closeCanvas(){var p=document.getElementById('canvasPanel');if(p)p.class
729
733
  function canvasCopyText(){
730
734
  var d=getConvCanvasData();var item=d.canvases[canvasIdx];
731
735
  if(!item){alert('No canvas content');return;}
732
- // Extract text from the HTML
733
- var tmp=document.createElement('div');tmp.innerHTML=item.html.replace(/<script[\s\S]*?<\/script>/gi,'');
736
+ var tmp=document.createElement('div');tmp.innerHTML=item.html.replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi,'');
734
737
  var text=tmp.textContent||tmp.innerText||'';
735
738
  navigator.clipboard.writeText(text).then(function(){alert('Text copied!')}).catch(function(){alert('Copy failed')});
736
739
  }
@@ -743,33 +746,32 @@ function canvasCopyImage(){
743
746
  var f=document.getElementById('canvasFrame');
744
747
  if(!f){alert('No canvas frame');return;}
745
748
  try{
746
- // Use html2canvas approach — render iframe to canvas then copy
747
- var iframe=f;
748
- // For sandboxed iframes, we capture via srcdoc render
749
- var w=iframe.offsetWidth||800;var h=iframe.offsetHeight||400;
750
- var canvas=document.createElement('canvas');canvas.width=w*2;canvas.height=h*2;
751
- var ctx=canvas.getContext('2d');ctx.scale(2,2);
752
- // Draw white background
753
- ctx.fillStyle='#0a0a0a';ctx.fillRect(0,0,w,h);
754
- // Render the srcdoc HTML to an image via SVG foreignObject
749
+ // Ask the iframe to capture itself via postMessage
750
+ // Inject a capture script into the iframe
755
751
  var d=getConvCanvasData();var item=d.canvases[canvasIdx];
756
752
  if(!item){alert('No canvas');return;}
757
- var svg='<svg xmlns="http://www.w3.org/2000/svg" width="'+w+'" height="'+h+'"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" style="background:#0a0a0a">'+item.html.replace(/<script[\s\S]*?<\/script>/gi,'')+'</div></foreignObject></svg>';
758
- var img=new Image();
759
- img.onload=function(){
760
- ctx.drawImage(img,0,0,w,h);
761
- canvas.toBlob(function(blob){
762
- if(blob){
753
+ // Re-render with capture script added
754
+ var captureScript='<script>window.addEventListener("message",function(e){if(e.data==="capture"){try{var c=document.querySelector("canvas");if(c){window.parent.postMessage({type:"canvasCapture",dataUrl:c.toDataURL("image/png")},"*");return;}import("https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js").then(function(m){return m.default||window.html2canvas}).then(function(h2c){h2c(document.body,{backgroundColor:"#0a0a0a",scale:2}).then(function(cv){window.parent.postMessage({type:"canvasCapture",dataUrl:cv.toDataURL("image/png")},"*")})}).catch(function(){window.parent.postMessage({type:"canvasCapture",error:"Capture failed"},"*")})}catch(err){window.parent.postMessage({type:"canvasCapture",error:err.message},"*")}}});<\\/script>';
755
+ var htmlWithCapture=item.html.replace('</body>',captureScript+'</body>');
756
+ if(htmlWithCapture===item.html)htmlWithCapture=item.html+captureScript;
757
+ f.srcdoc=htmlWithCapture;
758
+ // Listen for the capture response
759
+ var handler=function(e){
760
+ if(e.data&&e.data.type==='canvasCapture'){
761
+ window.removeEventListener('message',handler);
762
+ if(e.data.error){alert('Capture failed: '+e.data.error);return;}
763
+ // Convert dataUrl to blob and copy/download
764
+ fetch(e.data.dataUrl).then(function(r){return r.blob()}).then(function(blob){
763
765
  navigator.clipboard.write([new ClipboardItem({'image/png':blob})]).then(function(){alert('Image copied!')}).catch(function(){
764
- // Fallback: download
765
- var a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='canvas.png';a.click();
766
+ var a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='canvas.png';a.click();alert('Image downloaded as canvas.png');
766
767
  });
767
- }
768
- },'image/png');
768
+ });
769
+ }
769
770
  };
770
- img.onerror=function(){alert('Image render failed — try Copy HTML instead');};
771
- img.src='data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svg);
772
- }catch(e){alert('Image copy failed: '+e.message);}
771
+ window.addEventListener('message',handler);
772
+ // Wait for iframe to load, then trigger capture
773
+ setTimeout(function(){f.contentWindow.postMessage('capture','*')},1500);
774
+ }catch(e){alert('Copy failed: '+e.message);}
773
775
  }
774
776
  function toggleCanvasSize(){
775
777
  var p=document.getElementById('canvasPanel');if(!p)return;
@@ -961,7 +963,7 @@ function sendChat(){
961
963
  if(data.markers.indexOf('[CANVAS_CLEAR]')!==-1)closeCanvas();
962
964
  }
963
965
  if(currentEvent==='tool_synthesis'){chatHistory[streamIdx].content='';renderMessages();}
964
- if(currentEvent==='done'){endStreaming();if(data.content){chatHistory[streamIdx].content=data.content.replace(/<think>[\\s\\S]*?<\\/think>/g,'').trim();}else{chatHistory[streamIdx].content=chatHistory[streamIdx].content.replace(/<think>[\\s\\S]*?<\\/think>/g,'').trim();}var ssf=data.screenshotFiles||[];for(var fi=0;fi<ssf.length;fi++){chatHistory[streamIdx].content+='\\n![Screenshot](/api/screenshots/'+ssf[fi]+')\\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(activeConvId){setTimeout(function(){loadConv(activeConvId);},500);}}
966
+ if(currentEvent==='done'){endStreaming();if(data.content){chatHistory[streamIdx].content=data.content.replace(/<think>[\\s\\S]*?<\\/think>/g,'').trim();}else{chatHistory[streamIdx].content=chatHistory[streamIdx].content.replace(/<think>[\\s\\S]*?<\\/think>/g,'').trim();}var ssf=data.screenshotFiles||[];for(var fi=0;fi<ssf.length;fi++){chatHistory[streamIdx].content+='\\n![Screenshot](/api/screenshots/'+ssf[fi]+')\\n';}if(data.inlineHtml){chatHistory[streamIdx].inlineHtml=data.inlineHtml;}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(activeConvId){setTimeout(function(){loadConv(activeConvId);},500);}}
965
967
  if(currentEvent==='error'){endStreaming();chatHistory[streamIdx].content='Error: '+(data.message||'Unknown');renderMessages();}
966
968
  }catch(e){}
967
969
  }