nothumanallowed 13.5.197 → 13.5.199
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 +5 -0
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +56 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.199",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). 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
|
@@ -3349,6 +3349,8 @@ export async function cmdUI(args) {
|
|
|
3349
3349
|
const body = await parseBody(req);
|
|
3350
3350
|
const task = (body.task || '').trim();
|
|
3351
3351
|
if (!task) { sendJSON(res, 400, { error: 'task required' }); logRequest(method, pathname, 400, Date.now() - start); return; }
|
|
3352
|
+
// Reload config so provider changes take effect immediately
|
|
3353
|
+
const config = loadConfig();
|
|
3352
3354
|
|
|
3353
3355
|
const plannerLang = (() => { const LANG_MAP2 = {en:'English',it:'Italian',es:'Spanish',fr:'French',de:'German',pt:'Portuguese',zh:'Chinese',ja:'Japanese',ar:'Arabic',hi:'Hindi',ru:'Russian',nl:'Dutch',pl:'Polish',tr:'Turkish',ko:'Korean'}; const lc = (config?.language||'it').slice(0,2); return LANG_MAP2[lc]||'Italian'; })();
|
|
3354
3356
|
|
|
@@ -3574,6 +3576,9 @@ Rules:
|
|
|
3574
3576
|
// ── Studio: run single step (SSE streaming) ──────────────────────
|
|
3575
3577
|
if (pathname === '/api/studio/run' && method === 'POST') {
|
|
3576
3578
|
const body = await parseBody(req, 4_194_304); // 4MB — context can be up to 120KB + task + PDF
|
|
3579
|
+
// Reload config on every request so provider/model/apiKey changes take effect immediately
|
|
3580
|
+
// (the top-level `config` is loaded once at startup and would be stale otherwise)
|
|
3581
|
+
const config = loadConfig();
|
|
3577
3582
|
const { agent, task, context, stepDef } = body;
|
|
3578
3583
|
const stepPdfBase64 = body.pdfBase64 || null;
|
|
3579
3584
|
const stepPdfName = body.pdfName || null;
|
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 = '13.5.
|
|
8
|
+
export const VERSION = '13.5.199';
|
|
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
|
@@ -4357,6 +4357,11 @@ function stopStudio() {
|
|
|
4357
4357
|
// Mark any still-running nodes as error
|
|
4358
4358
|
studioState.nodes.forEach(function(n) { if (n.status === 'running') n.status = 'error'; });
|
|
4359
4359
|
renderStudioNodes();
|
|
4360
|
+
// Save partial session so it appears in the sidebar with X button
|
|
4361
|
+
if (studioState.task && studioState.nodes.length > 0) {
|
|
4362
|
+
saveStudioSession(studioState.task + ' [Interrotta]', studioState.nodes, studioState.log, studioState.result || '');
|
|
4363
|
+
renderStudioSessionsBar();
|
|
4364
|
+
}
|
|
4360
4365
|
}
|
|
4361
4366
|
|
|
4362
4367
|
function studioReset() {
|
|
@@ -5194,8 +5199,37 @@ function downloadStudioPDF() {
|
|
|
5194
5199
|
var nodes = studioState.nodes || [];
|
|
5195
5200
|
var fileName = (task).slice(0, 60).replace(/[^a-z0-9\s]/gi,'').trim().replace(/\s+/g,'-') || 'NHA-Studio';
|
|
5196
5201
|
|
|
5197
|
-
//
|
|
5198
|
-
//
|
|
5202
|
+
// When a canvas HTML report exists, print IT directly — it's already pixel-perfect with
|
|
5203
|
+
// charts, tables and @media print CSS. No need to rebuild from markdown.
|
|
5204
|
+
if (studioState.canvas) {
|
|
5205
|
+
var canvasHtmlForPrint = studioState.canvas;
|
|
5206
|
+
var btn2c = document.getElementById('studioInlinePdfBtn');
|
|
5207
|
+
var dlBtn2c = document.querySelector('button[onclick="downloadStudioPDF()"]');
|
|
5208
|
+
function setBusyC(b) {
|
|
5209
|
+
if (btn2c) { btn2c.disabled = b; btn2c.textContent = b ? 'Generando PDF...' : '\u2913 PDF'; }
|
|
5210
|
+
if (dlBtn2c) { dlBtn2c.disabled = b; dlBtn2c.textContent = b ? 'Generando PDF...' : '\u2913 Download PDF'; }
|
|
5211
|
+
}
|
|
5212
|
+
setBusyC(true);
|
|
5213
|
+
var oldIfrC = document.getElementById('nhaPrintFrame');
|
|
5214
|
+
if (oldIfrC) oldIfrC.remove();
|
|
5215
|
+
var ifrC = document.createElement('iframe');
|
|
5216
|
+
ifrC.id = 'nhaPrintFrame';
|
|
5217
|
+
ifrC.style.cssText = 'position:fixed;top:-9999px;left:-9999px;width:1100px;height:800px;border:none;opacity:0;pointer-events:none';
|
|
5218
|
+
ifrC.onload = function() {
|
|
5219
|
+
setTimeout(function() {
|
|
5220
|
+
try { ifrC.contentWindow.focus(); ifrC.contentWindow.print(); } catch(e) {}
|
|
5221
|
+
setBusyC(false);
|
|
5222
|
+
setTimeout(function(){ try { ifrC.remove(); } catch(e){} }, 8000);
|
|
5223
|
+
}, 2500); // wait for Chart.js charts to render
|
|
5224
|
+
};
|
|
5225
|
+
document.body.appendChild(ifrC);
|
|
5226
|
+
try { ifrC.contentDocument.open(); ifrC.contentDocument.write(canvasHtmlForPrint); ifrC.contentDocument.close(); }
|
|
5227
|
+
catch(e) { ifrC.srcdoc = canvasHtmlForPrint; }
|
|
5228
|
+
setTimeout(function(){ setBusyC(false); }, 8000);
|
|
5229
|
+
return;
|
|
5230
|
+
}
|
|
5231
|
+
|
|
5232
|
+
// No canvas — generate the full text-based Studio PDF from agent markdown outputs.
|
|
5199
5233
|
|
|
5200
5234
|
// ── Markdown → HTML for PDF (full support: tables, lists, headers, inline) ──
|
|
5201
5235
|
function mdToPdfHtml(raw) {
|
|
@@ -6707,10 +6741,10 @@ function renderStudioSessionsBar() {
|
|
|
6707
6741
|
'</div>' +
|
|
6708
6742
|
'<div style="max-height:240px;overflow-y:auto;padding-right:2px;display:flex;flex-direction:column;gap:6px">' +
|
|
6709
6743
|
sessions.map(function(s,i) {
|
|
6710
|
-
return '<div style="background:#1e293b;border:1px solid #334155;border-radius:8px;padding:10px 12px">' +
|
|
6711
|
-
'<
|
|
6712
|
-
|
|
6713
|
-
'<
|
|
6744
|
+
return '<div style="background:#1e293b;border:1px solid #334155;border-radius:8px;padding:10px 12px;position:relative">' +
|
|
6745
|
+
'<button onclick="deleteStudioSession('+i+')" style="position:absolute;top:6px;right:6px;width:24px;height:24px;display:flex;align-items:center;justify-content:center;font-size:15px;line-height:1;background:#1e293b;border:1px solid #475569;border-radius:50%;color:#94a3b8;cursor:pointer;flex-shrink:0;z-index:1" title="Elimina sessione">×</button>' +
|
|
6746
|
+
'<div style="padding-right:28px;margin-bottom:7px">' +
|
|
6747
|
+
'<span style="font-size:11px;color:#f1f5f9;font-weight:600;line-height:1.4">' + esc(s.task.slice(0,65)) + (s.task.length>65?'...':'') + '</span>' +
|
|
6714
6748
|
'</div>' +
|
|
6715
6749
|
'<div style="font-size:10px;color:#64748b;margin-bottom:8px">' + esc(s.ts) + '</div>' +
|
|
6716
6750
|
'<div style="display:flex;gap:6px">' +
|
|
@@ -6822,20 +6856,14 @@ function restoreStudioSession(idx) {
|
|
|
6822
6856
|
}
|
|
6823
6857
|
// Restore canvas if present
|
|
6824
6858
|
if (s.canvas) {
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
var ct = document.getElementById('canvasTitle');
|
|
6830
|
-
if (ct) ct.textContent = 'Studio Report';
|
|
6859
|
+
studioState.canvas = s.canvas;
|
|
6860
|
+
// Use showCanvas() so allCanvasData is keyed correctly (activeConvId || '_default')
|
|
6861
|
+
// and renderCanvasPanel() is called, loading the iframe properly
|
|
6862
|
+
showCanvas(s.canvas, 'Studio Report: ' + s.task.slice(0, 50));
|
|
6831
6863
|
var scb = document.getElementById('studioCanvasBtn');
|
|
6832
6864
|
if (scb) scb.style.display = '';
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
if (!allCanvasData[convId]) allCanvasData[convId] = {canvases:[], browsers:[]};
|
|
6836
|
-
allCanvasData[convId].canvases.push({html: s.canvas, title: s.task.slice(0,60), ts: s.ts});
|
|
6837
|
-
canvasIdx = allCanvasData[convId].canvases.length - 1;
|
|
6838
|
-
canvasMode = 'canvas';
|
|
6865
|
+
var ct = document.getElementById('canvasTitle');
|
|
6866
|
+
if (ct) ct.textContent = 'Studio Report';
|
|
6839
6867
|
}
|
|
6840
6868
|
showToast('success', 'Session restored', s.task.slice(0, 60), 3000);
|
|
6841
6869
|
}
|
|
@@ -6961,6 +6989,16 @@ function runStudioStep(idx, node, task, context, stepDef, signal) {
|
|
|
6961
6989
|
var st = ev.token.replace(new RegExp(\x27[\\\\r\\\\n]+\x27,\x27g\x27), \x27 \x27);
|
|
6962
6990
|
// Strip surrounding brackets for display
|
|
6963
6991
|
var stLabel = st.replace(new RegExp(\x27^\\\\[\x27), \x27\x27).replace(new RegExp(\x27\\\\]\\\\s*$\x27), \x27\x27).trim();
|
|
6992
|
+
// If there is accumulated text before this status token, render it as markdown first
|
|
6993
|
+
var accText = output.trim();
|
|
6994
|
+
if (accText && tb.getAttribute(String.fromCharCode(100,97,116,97,45,114,108,101,110)) !== null) {
|
|
6995
|
+
// Render markdown of accumulated text so far, then append the new status chip below
|
|
6996
|
+
var mdRendered = renderMd(accText);
|
|
6997
|
+
tb.className = \x27studio-log-entry__text md-body\x27;
|
|
6998
|
+
tb.removeAttribute(String.fromCharCode(100,97,116,97,45,114,108,101,110));
|
|
6999
|
+
// Reset output accumulator for new section (keep full output for final render)
|
|
7000
|
+
tb.innerHTML = \x27<div class="md-body" style="margin-bottom:8px">\x27 + mdRendered + \x27</div>\x27;
|
|
7001
|
+
}
|
|
6964
7002
|
// Special chip for Searching
|
|
6965
7003
|
var srchM = st.match(new RegExp(\x27^\\\\[Searching:\\\\s*"([^"]+)"\\\\]\\\\s*$\x27));
|
|
6966
7004
|
if (srchM) {
|