nothumanallowed 13.5.61 → 13.5.63

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.61",
3
+ "version": "13.5.63",
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": {
@@ -4110,6 +4110,32 @@ ${completedHeadings ? `## SECTIONS ALREADY WRITTEN (headings only):\n${completed
4110
4110
  sendLog(` ✓ ${f.name}`);
4111
4111
  }
4112
4112
 
4113
+ // Post-process HTML files: remove meta tags that break HTTP iframe sandbox
4114
+ // (Strict-Transport-Security, X-Frame-Options, frame-ancestors CSP meta)
4115
+ // This is system-level sanitization — the generated project code is NOT modified
4116
+ // by hand; the sandbox shim layer strips incompatible production-only headers.
4117
+ const htmlFiles = files.filter(function(f) { return f.name.endsWith('.html'); });
4118
+ if (htmlFiles.length > 0) {
4119
+ sendLog('🔧 Sanitizzazione meta tag sandbox...');
4120
+ for (const f of htmlFiles) {
4121
+ const fp = path.join(sandboxDir, f.name);
4122
+ let html = fs.readFileSync(fp, 'utf8');
4123
+ const before = html.length;
4124
+ // Remove Strict-Transport-Security meta (forces HTTPS, breaks HTTP sandbox)
4125
+ html = html.replace(/<meta[^>]+Strict-Transport-Security[^>]*>/gi, '');
4126
+ // Remove X-Frame-Options meta (blocks iframe embedding)
4127
+ html = html.replace(/<meta[^>]+X-Frame-Options[^>]*>/gi, '');
4128
+ // Remove Content-Security-Policy meta http-equiv (server sets it via helmet with sandbox-safe values)
4129
+ html = html.replace(/<meta[^>]+http-equiv=["']Content-Security-Policy["'][^>]*>/gi, '');
4130
+ // Remove frame-ancestors none/self directives from any remaining CSP meta
4131
+ html = html.replace(/<meta[^>]+content=["'][^"']*frame-ancestors[^"']*["'][^>]*>/gi, '');
4132
+ if (html.length !== before) {
4133
+ fs.writeFileSync(fp, html, 'utf8');
4134
+ sendLog(' ✓ ' + f.name + ' (meta tag produzione rimossi)');
4135
+ }
4136
+ }
4137
+ }
4138
+
4113
4139
  // Inject sandbox db shim — replaces pg with in-memory SQLite-like store
4114
4140
  const dbShim = `
4115
4141
  // NHA WebCraft Sandbox DB Shim
@@ -4690,7 +4716,9 @@ REGOLE CRITICHE:
4690
4716
  content = content.replace(toolCall.old, toolCall.new);
4691
4717
  fs.writeFileSync(fp, content, 'utf8');
4692
4718
  toolResults.push({ op: 'edit', path: toolCall.path, ok: true });
4693
- sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'ok' });
4719
+ sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'ok',
4720
+ oldSnippet: (toolCall.old || '').slice(0, 300),
4721
+ newSnippet: (toolCall.new || '').slice(0, 300) });
4694
4722
  } else {
4695
4723
  sendEv({ type: 'tool', op: 'edit', path: toolCall.path, result: 'old_string non trovato — patch fallita' });
4696
4724
  }
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.61';
8
+ export const VERSION = '13.5.62';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -6989,6 +6989,7 @@ function wcChatPanelHtml() {
6989
6989
  }).join('') + '</div>';
6990
6990
  }
6991
6991
  } else {
6992
+ var diffBlocks = '';
6992
6993
  var toolBadges = (msg.tools || []).map(function(tool){
6993
6994
  var isOk = tool.result === 'ok';
6994
6995
  var isParseErr = tool.op === 'parse_error';
@@ -6996,6 +6997,17 @@ function wcChatPanelHtml() {
6996
6997
  var color = isOk ? 'var(--green)' : 'var(--red)';
6997
6998
  var label = isParseErr ? ('JSON err: ' + wcEsc(tool.result)) : wcEsc(tool.path);
6998
6999
  var title = isOk ? tool.op + ': ' + tool.path : (tool.result || '');
7000
+ // Build inline diff block for successful edits
7001
+ if (isOk && tool.op === 'edit' && tool.oldSnippet) {
7002
+ var oldLines = tool.oldSnippet.split(String.fromCharCode(10)).map(function(l){ return '<div style="background:#3f0f0f;color:#fca5a5;font-family:var(--mono);font-size:9px;padding:0 8px;white-space:pre-wrap;word-break:break-all">- '+wcEsc(l)+'</div>'; }).join('');
7003
+ var newLines = tool.newSnippet.split(String.fromCharCode(10)).map(function(l){ return '<div style="background:#0f2f0f;color:#86efac;font-family:var(--mono);font-size:9px;padding:0 8px;white-space:pre-wrap;word-break:break-all">+ '+wcEsc(l)+'</div>'; }).join('');
7004
+ diffBlocks += '<details style="margin:2px 0;border:1px solid rgba(255,255,255,0.08);border-radius:5px;overflow:hidden">' +
7005
+ '<summary style="padding:3px 8px;font-size:9px;font-family:var(--mono);color:var(--dim);cursor:pointer;list-style:none;display:flex;align-items:center;gap:4px">' +
7006
+ '<span style="color:var(--green)">&#9998;</span> '+wcEsc(tool.path)+' <span style="margin-left:auto;opacity:.5">&#9660;</span>' +
7007
+ '</summary>' +
7008
+ oldLines + newLines +
7009
+ '</details>';
7010
+ }
6999
7011
  return '<span title="'+wcEsc(title)+'" style="display:inline-flex;align-items:center;gap:3px;background:var(--bg3);border:1px solid '+(isOk?'var(--green3)':'var(--red)')+';border-radius:4px;padding:2px 6px;font-size:9px;font-family:var(--mono);color:'+color+'">' +
7000
7012
  icon + ' ' + label + '</span>';
7001
7013
  }).join(' ');
@@ -7006,6 +7018,7 @@ function wcChatPanelHtml() {
7006
7018
  '<span style="font-size:10px;font-weight:700;color:var(--green)">WebCraft Agent</span>' +
7007
7019
  '</div>' +
7008
7020
  '<div style="padding:8px 10px;font-size:11px;color:var(--text);line-height:1.6;white-space:pre-wrap">'+agentText+'</div>' +
7021
+ (diffBlocks ? '<div style="padding:4px 8px 6px;border-top:1px solid rgba(255,255,255,0.06)">'+diffBlocks+'</div>' : '') +
7009
7022
  (toolBadges ? '<div style="display:flex;flex-wrap:wrap;gap:4px;padding:6px 10px;border-top:1px solid rgba(255,255,255,0.06)">'+toolBadges+'</div>' : '') +
7010
7023
  '</div>';
7011
7024
  }
@@ -7190,7 +7203,7 @@ async function wcExecuteAgentCall(message, isPlanExec, planOrigMsg, attachments)
7190
7203
  if (typingEl) typingEl.textContent = '...';
7191
7204
  wcScrollChatToBottom();
7192
7205
  } else if (ev.type === 'tool') {
7193
- agentMsg.tools.push({ op: ev.op, path: ev.path, result: ev.result });
7206
+ agentMsg.tools.push({ op: ev.op, path: ev.path, result: ev.result, oldSnippet: ev.oldSnippet || '', newSnippet: ev.newSnippet || '' });
7194
7207
  if ((ev.op === 'edit' || ev.op === 'write') && ev.result === 'ok') {
7195
7208
  anyEdits = true;
7196
7209
  wcChat[wcChat.length-1] = agentMsg;
@@ -7310,7 +7323,7 @@ async function wcTriggerAutoFix(missingModule) {
7310
7323
  try {
7311
7324
  var ev2 = JSON.parse(line2);
7312
7325
  if (ev2.type === 'text') { agentMsg.text += ev2.token; }
7313
- else if (ev2.type === 'tool') { agentMsg.tools.push({ op: ev2.op, path: ev2.path, result: ev2.result }); }
7326
+ else if (ev2.type === 'tool') { agentMsg.tools.push({ op: ev2.op, path: ev2.path, result: ev2.result, oldSnippet: ev2.oldSnippet || '', newSnippet: ev2.newSnippet || '' }); }
7314
7327
  else if (ev2.type === 'done') { wcChatRunning = false; if (ev2.changed) { wcReloadProjectFiles(); } }
7315
7328
  else if (ev2.type === 'restart_sandbox') { wcStartSandbox(); }
7316
7329
  else if (ev2.type === 'error') { agentMsg.text += String.fromCharCode(10)+'Errore: '+ev2.msg; wcChatRunning = false; }
@@ -7637,7 +7650,7 @@ async function wcGenerate() {
7637
7650
 
7638
7651
  // Security rules always injected
7639
7652
  var SECURITY_RULES = [
7640
- 'ALWAYS use security headers: X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy: geolocation=(), microphone=(), camera=(), Strict-Transport-Security: max-age=31536000; includeSubDomains; preload.',
7653
+ 'ALWAYS use security headers via Express/helmet server-side only. NEVER add X-Frame-Options, Strict-Transport-Security, frame-ancestors, or Content-Security-Policy as HTML meta http-equiv tags — the app runs inside an HTTP iframe sandbox and these meta tags will break resource loading. Only allowed HTML security meta: viewport, charset, X-UA-Compatible, Permissions-Policy.',
7641
7654
  'NEVER put secrets, API keys, or DB credentials in frontend code. Only in .env server-side.',
7642
7655
  'ALWAYS use prepared statements / parameterized queries. NEVER string-concatenate SQL.',
7643
7656
  'ALWAYS hash passwords with bcrypt (cost factor 12+). NEVER store plain passwords.',
@@ -7657,7 +7670,7 @@ async function wcGenerate() {
7657
7670
  { name: 'package.json', lang: 'json', prompt: 'Generate package.json for an Express/PostgreSQL project named "'+projName+'". Dependencies: express, pg, bcryptjs, jsonwebtoken, nodemailer, helmet, express-rate-limit, cors, dotenv, express-validator, ioredis. DevDependencies: nodemon. Scripts: start, dev.' },
7658
7671
  { name: '.env.example', lang: 'bash', prompt: 'Generate .env.example with all required env vars: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASS, JWT_SECRET, JWT_REFRESH_SECRET, SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM, SENDGRID_API_KEY (commented as optional fallback), REDIS_URL (default redis://localhost:6379, works with Dragonfly too), PORT, NODE_ENV, CORS_ORIGIN, BASE_URL. Add helpful comments for each. Note that REDIS_URL is optional — app falls back to in-memory LRU if Redis unavailable.' },
7659
7672
  { name: 'server/db.js', lang: 'javascript', prompt: 'Generate server/db.js: pg.Pool singleton (max:10, idleTimeoutMillis:30000, connectionTimeoutMillis:2000). Circuit breaker: if DB fails 5+ times in 60s, open circuit (throw immediately) for 30s, then half-open (try one query). Export pool, query(text, params) with circuit breaker, transaction(callback) helper (BEGIN/COMMIT/ROLLBACK). Graceful shutdown on SIGTERM/SIGINT.' },
7660
- { name: 'server/middleware/security.js', lang: 'javascript', prompt: 'Generate server/middleware/security.js: helmet with full CSP (defaultSrc self, scriptSrc self, styleSrc self unsafe-inline, imgSrc self data:, connectSrc self, frameSrc none, objectSrc none), HSTS, X-Frame-Options DENY, Referrer-Policy. Add express-rate-limit for general routes (100/15min) and strict limiter for auth (5/15min). Export { applySecurityMiddleware, authLimiter }.' },
7673
+ { name: 'server/middleware/security.js', lang: 'javascript', prompt: 'Generate server/middleware/security.js: detect sandbox via isSandbox = !process.env.NODE_ENV || process.env.NODE_ENV === "development". Use helmet CSP: defaultSrc self, scriptSrc self unsafe-inline, styleSrc self unsafe-inline, imgSrc self data:, connectSrc self, objectSrc none. frameAncestors: if isSandbox use ["self", "http://127.0.0.1:*", "http://localhost:*"] else ["none"]. NO X-Frame-Options DENY (conflicts with frameAncestors). NO HSTS in sandbox (HTTP only). Referrer-Policy strict-origin-when-cross-origin. Add express-rate-limit for general routes (100/15min) and strict limiter for auth (5/15min). Export { applySecurityMiddleware, authLimiter }.' },
7661
7674
  { name: 'server/middleware/validate.js', lang: 'javascript', prompt: 'Generate server/middleware/validate.js using express-validator. Export handleValidationErrors middleware. Export auth field validators: registerValidator (fields: '+authFieldsDef+'), loginValidator (email + password).' },
7662
7675
  { name: 'server/services/email.js', lang: 'javascript', prompt: 'Generate server/services/email.js: Nodemailer transporter using SMTP from env. Function sendVerificationEmail(to, token, baseUrl): sends HTML email with verification link. Function sendPasswordResetEmail(to, token, baseUrl). Add SendGrid fallback (commented out, predisposed with transporter swap). Never expose credentials.' },
7663
7676
  { name: 'server/routes/auth.js', lang: 'javascript', prompt: 'Generate server/routes/auth.js: POST /register (validate fields: '+authFieldsDef+', check duplicate email, bcrypt hash password cost 12, insert user, send verification email, return 201), POST /login (validate, check email verified, compare bcrypt, issue JWT access 15min + refresh 7d httpOnly cookie), POST /logout (clear refresh cookie), POST /refresh-token (validate refresh from httpOnly cookie, rotate token), GET /verify-email/:token (mark email verified). Use parameterized queries only. Apply authLimiter to register and login.' },
@@ -7668,9 +7681,9 @@ async function wcGenerate() {
7668
7681
  { name: 'public/css/components.css', lang: 'css', prompt: 'Generate public/css/components.css following STRICT BEM (block__element--modifier). Components: .btn (--primary, --secondary, --danger, --ghost), .form (form__field, form__label, form__input, form__error, form__hint), .card (card__header, card__body, card__footer), .nav (nav__brand, nav__links, nav__link--active), .alert (--success, --error, --warning, --info), .spinner, .badge, .modal (modal__overlay, modal__content, modal__header, modal__body, modal__footer). Fully accessible (focus states, aria).' },
7669
7682
  { name: 'public/css/pages.css', lang: 'css', prompt: 'Generate public/css/pages.css: page-level layout classes using BEM. .page-auth (centered card layout for login/register), .page-dashboard (sidebar + content grid), .page-landing (hero section, features grid, pricing cards). Responsive at 768px and 480px breakpoints.' },
7670
7683
  { name: 'public/js/main.js', lang: 'javascript', prompt: 'Generate public/js/main.js: vanilla JS, no dependencies. authAPI object with methods register(data), login(data), logout(), refreshToken(), getMe(). Cookie banner controller: reads localStorage consent, shows banner if not set, sets consent by category (necessary/analytics/marketing). Form handlers for register and login pages. Global error display utility. Export nothing (IIFE).' },
7671
- { name: 'public/index.html', lang: 'html', prompt: 'Generate public/index.html for "'+projName+'": '+desc+'. Full HTML5. Security meta tags (CSP via meta as fallback, X-UA-Compatible). Include base.css, components.css, pages.css. GDPR cookie banner HTML (class .cookie-banner, .cookie-banner__text, .cookie-banner__actions, .cookie-banner__btn--accept, .cookie-banner__btn--reject). Navigation. Hero section. Include main.js at end of body. Semantic HTML, ARIA roles, lang attribute.' },
7672
- { name: 'public/login.html', lang: 'html', prompt: 'Generate public/login.html: login page for "'+projName+'". Form with email + password fields using .form BEM classes. Link to register.html. Error display area. Include same CSS files. ARIA labels, autocomplete attributes.' },
7673
- { name: 'public/register.html', lang: 'html', prompt: 'Generate public/register.html: registration page for "'+projName+'". Form fields: '+authFieldsDef+'. Use .form BEM classes. Client-side validation hints. Link to login.html. Error/success display. Include same CSS files. ARIA labels, autocomplete attributes.' },
7684
+ { name: 'public/index.html', lang: 'html', prompt: 'Generate public/index.html for "'+projName+'": '+desc+'. Full HTML5. IMPORTANT: do NOT add X-Frame-Options, Strict-Transport-Security, or frame-ancestors meta tags the app runs in an iframe sandbox on HTTP localhost and these will break it. Only add: X-UA-Compatible IE=edge, viewport, charset, Permissions-Policy (geolocation=(), microphone=(), camera=()). Include base.css, components.css, pages.css. GDPR cookie banner HTML (class .cookie-banner, .cookie-banner__text, .cookie-banner__actions, .cookie-banner__btn--accept, .cookie-banner__btn--reject). Navigation. Hero section. Include main.js at end of body. Semantic HTML, ARIA roles, lang attribute.' },
7685
+ { name: 'public/login.html', lang: 'html', prompt: 'Generate public/login.html: login page for "'+projName+'". Form with email + password fields using .form BEM classes. Link to register.html. Error display area. Include same CSS files. ARIA labels, autocomplete attributes. Do NOT add X-Frame-Options or Strict-Transport-Security meta tags.' },
7686
+ { name: 'public/register.html', lang: 'html', prompt: 'Generate public/register.html: registration page for "'+projName+'". Form fields: '+authFieldsDef+'. Use .form BEM classes. Client-side validation hints. Link to login.html. Error/success display. Include same CSS files. ARIA labels, autocomplete attributes. Do NOT add X-Frame-Options or Strict-Transport-Security meta tags.' },
7674
7687
  { name: 'server/middleware/sentinel.js', lang: 'javascript', prompt: 'Generate server/middleware/sentinel.js: a lightweight WAF middleware for Express. Check request for: SQL injection patterns (UNION SELECT, DROP TABLE, etc.), XSS patterns (<script, javascript:, onerror=), path traversal (../), oversized payloads (>100KB body). Rate limit by IP using an in-memory sliding window (fallback when Redis unavailable). Log blocked requests with IP, method, path, reason to stderr. Export sentinelMiddleware(req, res, next).' },
7675
7688
  { name: 'server/services/cache.js', lang: 'javascript', prompt: 'Generate server/services/cache.js: Redis/Dragonfly client using ioredis. Connect to REDIS_URL from env. Export: get(key), set(key, value, ttlSeconds), del(key), exists(key). Add circuit breaker pattern: if Redis fails 3+ times in 30s, switch to in-memory LRU fallback (Map with max 1000 entries, LRU eviction). Reconnect Redis in background every 60s. Log circuit state changes. This makes the app resilient when Redis is down.' },
7676
7689
  { name: 'README.md', lang: 'markdown', prompt: 'Generate README.md for "'+projName+'": project description, tech stack (Express, PostgreSQL with circuit breaker, Redis/Dragonfly with LRU fallback, JWT auth, Nodemailer SMTP + SendGrid fallback, Sentinel WAF, BEM CSS), folder structure, setup instructions (clone, npm install, copy .env.example to .env, run migrations with psql, optional: start Redis/Dragonfly, npm run dev), environment variables table (including REDIS_URL), API endpoints table, security notes, email configuration guide.' },