nothumanallowed 12.2.0 → 12.3.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 +28 -10
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.3.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": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -1904,19 +1904,20 @@ export async function cmdUI(args) {
|
|
|
1904
1904
|
toolResults.push({ action, result: resultStr });
|
|
1905
1905
|
sendSSE('tool', { action, status: 'done', result: typeof resultStr === 'string' ? resultStr.slice(0, 500) : '' });
|
|
1906
1906
|
|
|
1907
|
-
// After web_search: open first result in browser +
|
|
1907
|
+
// After web_search: open first result in browser + embed inline card + inline browser
|
|
1908
1908
|
if (action === 'web_search' && resultStr.length > 50) {
|
|
1909
1909
|
try {
|
|
1910
1910
|
// Extract first URL from results
|
|
1911
1911
|
const urlMatch = resultStr.match(/https?:\/\/[^\s)<]+/);
|
|
1912
|
+
let inlineBrowserMarker = '';
|
|
1913
|
+
|
|
1912
1914
|
if (urlMatch) {
|
|
1913
1915
|
const be = await import('../services/browser-engine.mjs');
|
|
1914
1916
|
sendSSE('tool', { action: 'browser_open', status: 'executing' });
|
|
1915
1917
|
await be.browserOpen(urlMatch[0]);
|
|
1916
1918
|
sendSSE('tool', { action: 'browser_open', status: 'done', result: 'Opened ' + urlMatch[0] });
|
|
1917
|
-
// Capture frame for monitor
|
|
1918
1919
|
await new Promise(r => setTimeout(r, 1500));
|
|
1919
|
-
const frame = await be.browserScreenshot({ fullPage: false, format: 'jpeg', quality:
|
|
1920
|
+
const frame = await be.browserScreenshot({ fullPage: false, format: 'jpeg', quality: 50 });
|
|
1920
1921
|
if (!frame.error) {
|
|
1921
1922
|
const info = await be.browserInfo();
|
|
1922
1923
|
const thumbDir = path.join(NHA_DIR, 'screenshots');
|
|
@@ -1925,19 +1926,36 @@ export async function cmdUI(args) {
|
|
|
1925
1926
|
fs.writeFileSync(path.join(thumbDir, thumbFile), Buffer.from(frame.base64, 'base64'));
|
|
1926
1927
|
if (!res._browserThumbs) res._browserThumbs = [];
|
|
1927
1928
|
res._browserThumbs.push({ file: thumbFile, url: (info.url || '').slice(0, 80) });
|
|
1929
|
+
// Also send for floating panel (backwards compat)
|
|
1928
1930
|
sendSSE('browser_frame', { file: thumbFile, format: 'jpeg', url: (info.url || '').slice(0, 80) });
|
|
1931
|
+
// Inline browser marker — will be embedded in the response
|
|
1932
|
+
inlineBrowserMarker = `[INLINE_BROWSER]${thumbFile}|${(info.url || urlMatch[0]).slice(0, 80)}[/INLINE_BROWSER]`;
|
|
1929
1933
|
}
|
|
1930
1934
|
}
|
|
1931
1935
|
|
|
1932
|
-
//
|
|
1936
|
+
// Build inline card with structured search results
|
|
1933
1937
|
const lines = resultStr.split('\n').filter(l => l.trim());
|
|
1934
|
-
|
|
1938
|
+
let cardHtml = '<div style="font-family:system-ui;font-size:13px">';
|
|
1939
|
+
lines.slice(0, 8).forEach(l => {
|
|
1935
1940
|
const um = l.match(/https?:\/\/[^\s)]+/);
|
|
1936
|
-
const title = l.replace(/^\d+\.\s*/, '').replace(/https?:\/\/\S+/g, '').trim();
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
+
const title = l.replace(/^\d+\.\s*/, '').replace(/https?:\/\/\S+/g, '').replace(/<[^>]+>/g, '').trim();
|
|
1942
|
+
if (title) {
|
|
1943
|
+
cardHtml += '<div style="padding:8px 10px;border-bottom:1px solid #1e1e1e">';
|
|
1944
|
+
if (um) cardHtml += '<a href="' + um[0] + '" target="_blank" style="color:#00e5ff;text-decoration:none;font-size:13px">';
|
|
1945
|
+
cardHtml += title.replace(/&/g, '&').replace(/</g, '<');
|
|
1946
|
+
if (um) cardHtml += '<div style="font-size:10px;color:#555;margin-top:2px">' + um[0].replace(/&/g, '&').replace(/</g, '<') + '</div></a>';
|
|
1947
|
+
cardHtml += '</div>';
|
|
1948
|
+
}
|
|
1949
|
+
});
|
|
1950
|
+
cardHtml += '</div>';
|
|
1951
|
+
|
|
1952
|
+
// Append inline markers to the tool result so they end up in the response
|
|
1953
|
+
if (inlineBrowserMarker || cardHtml.length > 50) {
|
|
1954
|
+
const inlineMarkers = (inlineBrowserMarker ? inlineBrowserMarker + '\n' : '') + '[INLINE_CARD]' + cardHtml + '[/INLINE_CARD]';
|
|
1955
|
+
// Append to the last tool result so LLM includes it in response
|
|
1956
|
+
toolResults[toolResults.length - 1].result += '\n' + inlineMarkers;
|
|
1957
|
+
}
|
|
1958
|
+
} catch { /* non-critical */ }
|
|
1941
1959
|
}
|
|
1942
1960
|
|
|
1943
1961
|
// Send live browser frame after browser/search/fetch actions — save as thumbnail file for persistence
|
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.
|
|
8
|
+
export const VERSION = '12.3.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
|
@@ -112,6 +112,15 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
112
112
|
.tool-indicator--web{border-color:var(--cyan);color:var(--cyan)}
|
|
113
113
|
.tool-indicator--email{border-color:var(--green3);color:var(--green)}
|
|
114
114
|
.screenshot-preview{max-width:100%;border-radius:var(--r);margin:8px 0;border:1px solid var(--border)}
|
|
115
|
+
.inline-card{margin:12px 0;padding:0;border-radius:10px;border:1px solid var(--border);overflow:hidden;background:var(--bg2)}
|
|
116
|
+
.inline-card iframe{width:100%;height:280px;border:none;border-radius:0 0 10px 10px}
|
|
117
|
+
.inline-card a{color:var(--cyan);text-decoration:none}
|
|
118
|
+
.inline-card a:hover{text-decoration:underline}
|
|
119
|
+
.inline-browser{margin:12px 0;border-radius:10px;border:1px solid var(--green3);overflow:hidden;background:#000}
|
|
120
|
+
.inline-browser-bar{display:flex;align-items:center;gap:6px;padding:6px 10px;background:var(--bg);border-bottom:1px solid var(--border)}
|
|
121
|
+
.inline-browser-dot{width:8px;height:8px;border-radius:50%;background:var(--border2)}
|
|
122
|
+
.inline-browser-url{font-family:var(--mono);font-size:10px;color:var(--dim);flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
123
|
+
.inline-browser img{width:100%;display:block}
|
|
115
124
|
.browser-viewer{position:fixed;top:12px;left:12px;width:440px;background:var(--bg2);border:2px solid #9c27b0;border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,0.6);z-index:300;overflow:hidden;display:none;transition:all .3s ease}
|
|
116
125
|
.browser-viewer--open{display:block}
|
|
117
126
|
.browser-viewer__header{display:flex;align-items:center;gap:6px;padding:6px 10px;background:#1a1a2e;border-bottom:1px solid #9c27b0;font-size:10px;color:#ce93d8}
|
|
@@ -466,6 +475,10 @@ function renderMessages(){
|
|
|
466
475
|
var cm=raw.match(/\\[CANVAS_RENDER\\]([\\s\\S]*?)\\[\\/CANVAS_RENDER\\]/);
|
|
467
476
|
if(cm){try{var cd=JSON.parse(cm[1]);showCanvas(cd.html,cd.title);}catch(e){} raw=raw.replace(/\\[CANVAS_RENDER\\][\\s\\S]*?\\[\\/CANVAS_RENDER\\]/,'').trim();}
|
|
468
477
|
if(raw.indexOf('[CANVAS_CLEAR]')!==-1){closeCanvas();raw=raw.replace(/\\[CANVAS_CLEAR\\][\\s\\S]*?\\[\\/CANVAS_CLEAR\\]/,'').trim();}
|
|
478
|
+
// Inline cards — rendered as embedded HTML inside the message
|
|
479
|
+
raw=raw.replace(/\\[INLINE_CARD\\]([\\s\\S]*?)\\[\\/INLINE_CARD\\]/g,function(_,html){return '<div class="inline-card">'+html+'</div>';});
|
|
480
|
+
// Inline browser frame — rendered as embedded image inside the message
|
|
481
|
+
raw=raw.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>';});
|
|
469
482
|
// Handle screenshot file markers
|
|
470
483
|
var sm=raw.match(/\\[SCREENSHOT_FILE\\](.*?)\\[\\/SCREENSHOT_FILE\\]/);
|
|
471
484
|
if(sm){var fn=sm[1].split('/').pop();raw=raw.replace(/\\[SCREENSHOT_FILE\\].*?\\[\\/SCREENSHOT_FILE\\]/,'');raw='\\n'+raw;}
|