nothumanallowed 13.5.71 → 13.5.73

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.5.71",
3
+ "version": "13.5.73",
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": {
@@ -4278,6 +4278,50 @@ module.exports = { get, set, del, exists };
4278
4278
  fs.mkdirSync(path.join(sandboxDir, 'server', 'services'), { recursive: true });
4279
4279
  fs.writeFileSync(path.join(sandboxDir, 'server', 'services', 'cache.js'), cacheShim, 'utf8');
4280
4280
 
4281
+ // Errors middleware shim — LLM often generates a custom error handler middleware file
4282
+ const errorsShim = `
4283
+ // NHA WebCraft Sandbox — middleware/errors shim
4284
+ class AppError extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode || 500; this.isOperational = true; } }
4285
+ function errorHandler(err, req, res, next) {
4286
+ var code = err.statusCode || err.status || 500;
4287
+ var msg = (process.env.NODE_ENV !== 'production' || err.isOperational) ? err.message : 'Internal Server Error';
4288
+ res.status(code).json({ error: msg });
4289
+ }
4290
+ module.exports = errorHandler;
4291
+ module.exports.AppError = AppError;
4292
+ module.exports.errorHandler = errorHandler;
4293
+ `;
4294
+ fs.mkdirSync(path.join(sandboxDir, 'server', 'middleware'), { recursive: true });
4295
+ if (!fs.existsSync(path.join(sandboxDir, 'server', 'middleware', 'errors.js'))) {
4296
+ fs.writeFileSync(path.join(sandboxDir, 'server', 'middleware', 'errors.js'), errorsShim, 'utf8');
4297
+ }
4298
+
4299
+ // Models shim — LLM often generates require('../models/User') etc. that don't exist
4300
+ // Create a generic User model shim backed by the in-memory DB shim
4301
+ const userModelShim = `
4302
+ // NHA WebCraft Sandbox — models/User shim (in-memory, no PostgreSQL)
4303
+ const db = require('../db');
4304
+ const bcrypt = require('bcryptjs');
4305
+ const crypto = require('crypto');
4306
+ const User = {
4307
+ findById: async function(id) { var r = await db.query('SELECT * FROM users WHERE id=$1',[id]); return (r.rows||[])[0]||null; },
4308
+ findByEmail: async function(email) { var r = await db.query('SELECT * FROM users WHERE email=$1',[email]); return (r.rows||[])[0]||null; },
4309
+ create: async function(data) {
4310
+ var hash = data.password ? await bcrypt.hash(data.password,12) : data.password_hash||'';
4311
+ var token = crypto.randomBytes(32).toString('hex');
4312
+ var r = await db.query('INSERT INTO users (name,email,password_hash,verification_token) VALUES ($1,$2,$3,$4) RETURNING *',[data.name||data.username||'',data.email,hash,token]);
4313
+ return (r.rows||[])[0]||null;
4314
+ },
4315
+ update: async function(id, data) { var r = await db.query('UPDATE users SET verified=true WHERE id=$1 RETURNING *',[id]); return (r.rows||[])[0]||null; },
4316
+ findByVerificationToken: async function(token) { var r = await db.query('SELECT * FROM users WHERE verification_token=$1',[token]); return (r.rows||[])[0]||null; },
4317
+ };
4318
+ module.exports = User;
4319
+ `;
4320
+ fs.mkdirSync(path.join(sandboxDir, 'server', 'models'), { recursive: true });
4321
+ if (!fs.existsSync(path.join(sandboxDir, 'server', 'models', 'User.js'))) {
4322
+ fs.writeFileSync(path.join(sandboxDir, 'server', 'models', 'User.js'), userModelShim, 'utf8');
4323
+ }
4324
+
4281
4325
  // Validators shim — LLM often generates require('../utils/validators') with helpers that don't exist
4282
4326
  const validatorsShim = `
4283
4327
  // NHA WebCraft Sandbox — utils/validators shim
@@ -4347,6 +4391,15 @@ module.exports = { validateEmail, sanitizeText, validatePassword, validateUserna
4347
4391
  [/require\(['"]\.\.\/\.\.\/config['"]\)/g, "{env:process.env}"],
4348
4392
  [/require\(['"]\.\.\/config['"]\)/g, "{env:process.env}"],
4349
4393
  [/require\(['"]\.\/config['"]\)/g, "{env:process.env}"],
4394
+ // middleware/errors — LLM generates a custom error handler that doesn't exist
4395
+ [/require\(['"]\.\.\/middleware\/errors['"]\)/g, "require('../middleware/errors')"],
4396
+ [/require\(['"]\.\/middleware\/errors['"]\)/g, "require('./middleware/errors')"],
4397
+ [/require\(['"]\.\.\/middleware\/errorHandler['"]\)/g, "require('../middleware/errors')"],
4398
+ [/require\(['"]\.\.\/middleware\/error['"]\)/g, "require('../middleware/errors')"],
4399
+ // models/* — redirect to shims in server/models/
4400
+ [/require\(['"]\.\.\/models\/User['"]\)/g, "require('../models/User')"],
4401
+ [/require\(['"]\.\/models\/User['"]\)/g, "require('./models/User')"],
4402
+ [/require\(['"]\.\.\/models\/user['"]\)/g, "require('../models/User')"],
4350
4403
  // utils/* — LLM generates helpers that don't exist; redirect to shim
4351
4404
  [/require\(['"]\.\.\/utils\/validators['"]\)/g, "require('../utils/validators')"],
4352
4405
  [/require\(['"]\.\/utils\/validators['"]\)/g, "require('./utils/validators')"],
@@ -4474,6 +4527,7 @@ module.exports = { validateEmail, sanitizeText, validatePassword, validateUserna
4474
4527
  global._wcSandboxPort = freePort;
4475
4528
  global._wcSandboxDir = sandboxDir;
4476
4529
 
4530
+ let _lastMissingModule = null;
4477
4531
  proc.stdout.on('data', d => { const l = d.toString().trim(); if (l) sendLog(' [server] ' + l); });
4478
4532
  proc.stderr.on('data', d => {
4479
4533
  const raw = d.toString();
@@ -4481,6 +4535,7 @@ module.exports = { validateEmail, sanitizeText, validatePassword, validateUserna
4481
4535
  const modMatch = raw.match(/Cannot find module '([^']+)'/);
4482
4536
  if (modMatch) {
4483
4537
  const missingMod = modMatch[1];
4538
+ _lastMissingModule = missingMod;
4484
4539
  sendLog(' ❌ Modulo mancante: ' + missingMod);
4485
4540
  // Store error for auto-fix agent — will be picked up by frontend
4486
4541
  if (!global._wcAutoFixQueue) global._wcAutoFixQueue = [];
@@ -4502,7 +4557,7 @@ module.exports = { validateEmail, sanitizeText, validatePassword, validateUserna
4502
4557
  s.on('connect', () => { s.destroy(); resolve(); });
4503
4558
  s.on('error', () => {
4504
4559
  s.destroy();
4505
- if (++attempts > 20) reject(new Error('Server non risponde dopo 10s'));
4560
+ if (++attempts > 20) reject(new Error(_lastMissingModule ? "Cannot find module '" + _lastMissingModule + "'" : 'Server non risponde dopo 10s'));
4506
4561
  else setTimeout(tryConnect, 500);
4507
4562
  });
4508
4563
  };
@@ -4589,14 +4644,14 @@ module.exports = { validateEmail, sanitizeText, validatePassword, validateUserna
4589
4644
  return;
4590
4645
  }
4591
4646
 
4592
- // Rate-limit Liara: 3 per 5 minutes
4647
+ // Rate-limit Liara: 6 per 5 minutes (autofix needs headroom for multi-crash startup sequences)
4593
4648
  const isLiara = !config.llm || !config.llm.apiKey || config.llm.provider === 'nha';
4594
4649
  if (isLiara) {
4595
4650
  if (!global._wcAgentCallLog) global._wcAgentCallLog = [];
4596
4651
  const fiveMinAgo = Date.now() - 5 * 60 * 1000;
4597
4652
  global._wcAgentCallLog = global._wcAgentCallLog.filter(t => t > fiveMinAgo);
4598
- if (global._wcAgentCallLog.length >= 3) {
4599
- sendJSON(res, 429, { error: 'Auto-fix rate limit: massimo 3 correzioni ogni 5 minuti con Liara. Usa una tua API key per correzioni illimitate.' });
4653
+ if (global._wcAgentCallLog.length >= 6) {
4654
+ sendJSON(res, 429, { error: 'Auto-fix rate limit: massimo 6 correzioni ogni 5 minuti con Liara. Usa una tua API key per correzioni illimitate.' });
4600
4655
  logRequest(method, pathname, 429, Date.now() - start);
4601
4656
  return;
4602
4657
  }
@@ -6565,10 +6565,10 @@ function wcEsc(s){return s?String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').
6565
6565
 
6566
6566
  function renderWebCraft(el) {
6567
6567
  var fileTabsHtml = wcState.generatedFiles.length > 0
6568
- ? '<div style="display:flex;gap:0;overflow-x:auto;border-bottom:1px solid var(--border);margin-bottom:0;flex-shrink:0">' +
6568
+ ? '<div id="wcFileTabsRow" style="display:flex;gap:0;overflow-x:auto;border-bottom:1px solid var(--border);margin-bottom:0;flex-shrink:0;scrollbar-width:none">' +
6569
6569
  wcState.generatedFiles.map(function(f,i){
6570
6570
  var active = i === wcState.activeFile;
6571
- return '<button onclick="wcSetFile('+i+')" style="padding:6px 14px;font-size:11px;font-family:var(--mono);font-weight:'+(active?'700':'400')+';background:'+(active?'var(--bg3)':'transparent')+';border:none;border-bottom:2px solid '+(active?'var(--green3)':'transparent')+';color:'+(active?'var(--green)':'var(--dim)')+';cursor:pointer;white-space:nowrap;flex-shrink:0">'+wcEsc(f.name)+'</button>';
6571
+ return '<button id="wcTab'+i+'" onclick="wcSetFile('+i+')" style="padding:6px 14px;font-size:11px;font-family:var(--mono);font-weight:'+(active?'700':'400')+';background:'+(active?'var(--bg3)':'transparent')+';border:none;border-bottom:2px solid '+(active?'var(--green3)':'transparent')+';color:'+(active?'var(--green)':'var(--dim)')+';cursor:pointer;white-space:nowrap;flex-shrink:0">'+wcEsc(f.name)+'</button>';
6572
6572
  }).join('') +
6573
6573
  '</div>'
6574
6574
  : '';
@@ -7366,7 +7366,7 @@ function wcStopAutoFixPoller() {
7366
7366
  async function wcTriggerAutoFix(missingModule) {
7367
7367
  if (wcChatRunning) return;
7368
7368
  var fixMsg = 'AUTO-FIX: Cannot find module ' + missingModule + String.fromCharCode(10) + 'Analizza tutti i file del progetto e correggi il require/import per questo modulo. Se il modulo non esiste, rimuovi il require e implementa la funzionalita con moduli disponibili o Node.js built-in.';
7369
- wcChat.push({ role: 'user', text: '&#129302; Auto-fix modulo mancante: ' + missingModule });
7369
+ wcChat.push({ role: 'user', text: '\uD83E\uDD16 Auto-fix modulo mancante: ' + missingModule });
7370
7370
  wcChatRunning = true;
7371
7371
  renderWebCraft(document.getElementById('content'));
7372
7372
  wcScrollChatToBottom();
@@ -7495,7 +7495,13 @@ function wcAddField() {
7495
7495
  wcState.authFields.push({name:'field'+wcState.authFields.length,label:'New field',type:'text',required:false});
7496
7496
  renderWebCraft(document.getElementById('content'));
7497
7497
  }
7498
- function wcSetFile(i) { wcState.activeFile = i; renderWebCraft(document.getElementById('content')); }
7498
+ function wcSetFile(i) {
7499
+ wcState.activeFile = i;
7500
+ renderWebCraft(document.getElementById('content'));
7501
+ // Scroll active tab into view after render
7502
+ var tab = document.getElementById('wcTab' + i);
7503
+ if (tab) tab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
7504
+ }
7499
7505
 
7500
7506
  // ── WebCraft: Diff Viewer ─────────────────────────────────────────────────────
7501
7507
  function wcDiffLines(before, after) {
@@ -8078,7 +8084,7 @@ async function wcFixSandboxError() {
8078
8084
  String.fromCharCode(10) + String.fromCharCode(10) +
8079
8085
  'STACKTRACE COMPLETO:' + String.fromCharCode(10) + errText;
8080
8086
  // Push as user message so it appears in chat
8081
- wcChat.push({ role: 'user', text: '&#129302; Correggi errore sandbox' });
8087
+ wcChat.push({ role: 'user', text: '\uD83E\uDD16 Correggi errore sandbox' });
8082
8088
  wcScrollChatToBottom();
8083
8089
  wcChatRunning = true;
8084
8090
  renderWebCraft(document.getElementById('content'));