nothumanallowed 13.2.66 → 13.2.68

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": "13.2.66",
3
+ "version": "13.2.68",
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/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.2.66';
8
+ export const VERSION = '13.2.68';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -3241,6 +3241,8 @@ function studioReset() {
3241
3241
  studioState.canvas = null;
3242
3242
  studioState.running = false;
3243
3243
  studioState.planned = false;
3244
+ studioState.attachmentContext = '';
3245
+ studioState.attachmentName = '';
3244
3246
  studioTokens = {in:0, out:0};
3245
3247
  var nudgeEl = document.getElementById(\x27studioParliamentNudge\x27);
3246
3248
  if (nudgeEl) nudgeEl.remove();
@@ -3253,6 +3255,42 @@ function studioReset() {
3253
3255
  renderStudioResult();
3254
3256
  }
3255
3257
 
3258
+ function studioClearAttach() {
3259
+ studioState.attachmentContext = '';
3260
+ studioState.attachmentName = '';
3261
+ var badge = document.getElementById('studioAttachBadge');
3262
+ if (badge) badge.remove();
3263
+ var fi = document.getElementById('studioFileInput');
3264
+ if (fi) fi.value = '';
3265
+ }
3266
+
3267
+ function studioHandleAttach(file) {
3268
+ if (!file) return;
3269
+ var name = file.name;
3270
+ var isPdf = name.toLowerCase().endsWith('.pdf');
3271
+ var isImg = new RegExp('[.](png|jpe?g|gif|webp)$', 'i').test(name);
3272
+ if (!isPdf && !isImg) { alert('Supported: PDF, PNG, JPG, GIF, WEBP'); return; }
3273
+
3274
+ var reader = new FileReader();
3275
+ reader.onload = function(ev) {
3276
+ var dataUrl = ev.target.result;
3277
+ studioState.attachmentName = name;
3278
+ studioState.attachmentContext = (isPdf ? '[ATTACHED PDF: ' : '[ATTACHED IMAGE: ') + name + ']' + String.fromCharCode(10) + 'Base64: ' + dataUrl;
3279
+ // Show badge inline without full re-render
3280
+ var inputRow = document.querySelector('.studio-input-row');
3281
+ if (inputRow) {
3282
+ var existing = document.getElementById('studioAttachBadge');
3283
+ if (existing) existing.remove();
3284
+ var badge = document.createElement('div');
3285
+ badge.id = 'studioAttachBadge';
3286
+ badge.style.cssText = 'display:flex;align-items:center;gap:6px;padding:4px 10px;background:var(--greendim);border:1px solid var(--green3);border-radius:6px;margin-bottom:6px;font-size:11px;color:var(--green);font-family:var(--mono)';
3287
+ badge.innerHTML = '&#128206; ' + esc(name) + ' <span onclick="studioClearAttach()" style="cursor:pointer;color:var(--dim);font-size:13px;margin-left:4px" title="Remove">&#215;</span>';
3288
+ inputRow.insertBefore(badge, inputRow.children[1]);
3289
+ }
3290
+ };
3291
+ reader.readAsDataURL(file);
3292
+ }
3293
+
3256
3294
  var STUDIO_EXAMPLES = [
3257
3295
  'Analyze my unread emails and create a priority action plan',
3258
3296
  'Search the web for AI news today and summarize it in a canvas report',
@@ -3398,11 +3436,17 @@ function downloadStudioPDF() {
3398
3436
  '<div class="footer-bar">NHA Studio &nbsp;·&nbsp; nothumanallowed.com &nbsp;·&nbsp; ' + today + '</div>' +
3399
3437
  '</body></html>';
3400
3438
 
3401
- var win = window.open('', '_blank');
3402
- if (!win) { alert('Popup bloccato — abilita i popup per scaricare il PDF'); return; }
3403
- win.document.write(html);
3404
- win.document.close();
3405
- win.onload = function() { setTimeout(function(){ win.print(); }, 300); };
3439
+ // Use Blob URL to avoid popup blockers — opens in new tab, user can Cmd+P to print as PDF
3440
+ var blob = new Blob([html], {type: 'text/html'});
3441
+ var url = URL.createObjectURL(blob);
3442
+ var a = document.createElement('a');
3443
+ a.href = url;
3444
+ a.target = '_blank';
3445
+ a.download = (studioState.task || 'NHA Studio Report').slice(0, 60).replace(/[^a-z0-9\s]/gi,'').trim().replace(/\s+/g,'-') + '.html';
3446
+ document.body.appendChild(a);
3447
+ a.click();
3448
+ document.body.removeChild(a);
3449
+ setTimeout(function(){ URL.revokeObjectURL(url); }, 5000);
3406
3450
  }
3407
3451
 
3408
3452
  function renderStudioResult() {
@@ -3453,6 +3497,7 @@ async function runStudio() {
3453
3497
  studioState.canvas = null;
3454
3498
  studioState.running = true;
3455
3499
  studioState.planned = false;
3500
+ // Keep attachmentContext — it was loaded before hitting Run
3456
3501
  renderStudioNodes();
3457
3502
  renderStudioLog();
3458
3503
  renderStudioResult();
@@ -3471,7 +3516,10 @@ async function runStudio() {
3471
3516
 
3472
3517
  try {
3473
3518
  // Step 1: plan the workflow
3474
- var planRes = await apiPost('/api/studio/plan', {task: task});
3519
+ var taskForPlan = studioState.attachmentContext
3520
+ ? task + '\n\n[User has attached a file: ' + studioState.attachmentName + '. Agents will receive the full content.]'
3521
+ : task;
3522
+ var planRes = await apiPost('/api/studio/plan', {task: taskForPlan});
3475
3523
  if (!planRes || !planRes.steps || !planRes.steps.length) {
3476
3524
  studioLog('Studio', '&#9888;', 'Could not plan workflow. Check your LLM provider config.', 'error');
3477
3525
  studioState.running = false;
@@ -3731,7 +3779,11 @@ function runStudioStep(idx, node, task, context, stepDef, signal) {
3731
3779
  return new Promise(function(resolve) {
3732
3780
  var output = '';
3733
3781
  var canvasHtml = null;
3734
- var body = JSON.stringify({stepIdx: idx, agent: node.agent, task: task, context: context, stepDef: stepDef});
3782
+ // Inject attachment context into first step (idx===0) if present
3783
+ var effectiveContext = (idx === 0 && studioState.attachmentContext)
3784
+ ? (studioState.attachmentContext + (context ? '\n\n' + context : ''))
3785
+ : context;
3786
+ var body = JSON.stringify({stepIdx: idx, agent: node.agent, task: task, context: effectiveContext, stepDef: stepDef});
3735
3787
  var fetchOpts = {method: 'POST', headers: {'Content-Type': 'application/json'}, body: body};
3736
3788
  if (signal) fetchOpts.signal = signal;
3737
3789
 
@@ -3904,7 +3956,10 @@ function renderStudio(el) {
3904
3956
  '</div>' +
3905
3957
  '<div class="studio-input-row">' +
3906
3958
  '<textarea id="studioTaskInput" placeholder="' + t('placeholder_studio') + '" onkeydown="if(event.key===\\x27Enter\\x27&&(event.ctrlKey||event.metaKey)){runStudio();event.preventDefault()}">' + esc(studioState.task) + '</textarea>' +
3959
+ (studioState.attachmentName ? '<div id="studioAttachBadge" style="display:flex;align-items:center;gap:6px;padding:4px 10px;background:var(--greendim);border:1px solid var(--green3);border-radius:6px;margin-bottom:6px;font-size:11px;color:var(--green);font-family:var(--mono)">&#128206; ' + esc(studioState.attachmentName) + ' <span onclick="studioClearAttach()" style="cursor:pointer;color:var(--dim);font-size:13px;margin-left:4px" title="Rimuovi">&#215;</span></div>' : '') +
3960
+ '<input type="file" id="studioFileInput" accept=".pdf,.png,.jpg,.jpeg,.gif,.webp" style="display:none" onchange="studioHandleAttach(this.files[0])">' +
3907
3961
  '<div style="display:flex;gap:6px">' +
3962
+ '<button onclick="document.getElementById(\\x27studioFileInput\\x27).click()" title="Attach PDF or image" style="padding:8px 10px;background:none;border:1px solid var(--border);border-radius:8px;color:var(--dim);cursor:pointer;font-size:15px" ' + (studioState.running ? 'disabled' : '') + '>&#128206;</button>' +
3908
3963
  '<button id="studioRunBtn" class="studio-run-btn" onclick="runStudio()" style="flex:1" ' + (studioState.running ? 'disabled' : '') + '>' + t('run') + '</button>' +
3909
3964
  '<button id="studioStopBtn" onclick="stopStudio()" title="' + t('stop') + '" style="padding:8px 14px;background:#7f1d1d;border:1px solid #ef4444;border-radius:8px;color:#ef4444;cursor:pointer;font-size:13px;font-weight:700;white-space:nowrap;' + (studioState.running ? '' : 'display:none') + '">&#9632; ' + t('stop') + '</button>' +
3910
3965
  '<button onclick="studioReset()" title="' + t('reset') + '" style="padding:8px 12px;background:none;border:1px solid var(--border);border-radius:8px;color:var(--dim);cursor:pointer;font-size:16px;line-height:1" ' + (studioState.running ? 'disabled' : '') + '>&#8635;</button>' +